diff options
Diffstat (limited to 'plugins/audio_opensles')
-rwxr-xr-x | plugins/audio_opensles/audio_opensles.cxx | 866 | ||||
-rwxr-xr-x | plugins/audio_opensles/audio_opensles.h | 6 | ||||
-rwxr-xr-x | plugins/audio_opensles/audio_opensles_config.h | 14 | ||||
-rwxr-xr-x | plugins/audio_opensles/audio_opensles_consumer.cxx | 347 | ||||
-rwxr-xr-x | plugins/audio_opensles/audio_opensles_consumer.h | 8 | ||||
-rwxr-xr-x | plugins/audio_opensles/audio_opensles_device.cxx | 938 | ||||
-rwxr-xr-x | plugins/audio_opensles/audio_opensles_device.h | 132 | ||||
-rwxr-xr-x | plugins/audio_opensles/audio_opensles_device_impl.cxx | 46 | ||||
-rwxr-xr-x | plugins/audio_opensles/audio_opensles_device_impl.h | 26 | ||||
-rwxr-xr-x | plugins/audio_opensles/audio_opensles_producer.cxx | 341 | ||||
-rwxr-xr-x | plugins/audio_opensles/audio_opensles_producer.h | 6 | ||||
-rwxr-xr-x | plugins/audio_opensles/dllmain.cxx | 25 |
12 files changed, 1385 insertions, 1370 deletions
diff --git a/plugins/audio_opensles/audio_opensles.cxx b/plugins/audio_opensles/audio_opensles.cxx index 0cf5ea3..1d2e864 100755 --- a/plugins/audio_opensles/audio_opensles.cxx +++ b/plugins/audio_opensles/audio_opensles.cxx @@ -1,17 +1,17 @@ /* Copyright (C) 2012 Doubango Telecom <http://www.doubango.org> -* +* * This file is part of Open Source Doubango Framework. * * DOUBANGO 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 3 of the License, or * (at your option) any later version. -* +* * DOUBANGO 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 DOUBANGO. */ @@ -29,93 +29,87 @@ #include "tsk_safeobj.h" #include "tsk_debug.h" -typedef enum PLUGIN_INDEX_E -{ - PLUGIN_INDEX_AUDIO_CONSUMER, - PLUGIN_INDEX_AUDIO_PRODUCER, - PLUGIN_INDEX_COUNT +typedef enum PLUGIN_INDEX_E { + PLUGIN_INDEX_AUDIO_CONSUMER, + PLUGIN_INDEX_AUDIO_PRODUCER, + PLUGIN_INDEX_COUNT } PLUGIN_INDEX_T; int __plugin_get_def_count() { - return PLUGIN_INDEX_COUNT; + return PLUGIN_INDEX_COUNT; } tsk_plugin_def_type_t __plugin_get_def_type_at(int index) { - switch(index){ - case PLUGIN_INDEX_AUDIO_CONSUMER: return tsk_plugin_def_type_consumer; - case PLUGIN_INDEX_AUDIO_PRODUCER: return tsk_plugin_def_type_producer; - default: - { - AUDIO_OPENSLES_DEBUG_ERROR("No plugin at index %d", index); - return tsk_plugin_def_type_none; - } - } + switch(index) { + case PLUGIN_INDEX_AUDIO_CONSUMER: + return tsk_plugin_def_type_consumer; + case PLUGIN_INDEX_AUDIO_PRODUCER: + return tsk_plugin_def_type_producer; + default: { + AUDIO_OPENSLES_DEBUG_ERROR("No plugin at index %d", index); + return tsk_plugin_def_type_none; + } + } } tsk_plugin_def_media_type_t __plugin_get_def_media_type_at(int index) { - switch(index){ - case PLUGIN_INDEX_AUDIO_CONSUMER: - case PLUGIN_INDEX_AUDIO_PRODUCER: - { - return tsk_plugin_def_media_type_audio; - } - default: - { - AUDIO_OPENSLES_DEBUG_ERROR("No plugin at index %d", index); - return tsk_plugin_def_media_type_none; - } - } + switch(index) { + case PLUGIN_INDEX_AUDIO_CONSUMER: + case PLUGIN_INDEX_AUDIO_PRODUCER: { + return tsk_plugin_def_media_type_audio; + } + default: { + AUDIO_OPENSLES_DEBUG_ERROR("No plugin at index %d", index); + return tsk_plugin_def_media_type_none; + } + } } tsk_plugin_def_ptr_const_t __plugin_get_def_at(int index) { - switch(index){ - case PLUGIN_INDEX_AUDIO_CONSUMER: - { - return audio_consumer_opensles_plugin_def_t; - } - case PLUGIN_INDEX_AUDIO_PRODUCER: - { - return audio_producer_opensles_plugin_def_t; - } - default: - { - AUDIO_OPENSLES_DEBUG_ERROR("No plugin at index %d", index); - return tsk_null; - } - } + switch(index) { + case PLUGIN_INDEX_AUDIO_CONSUMER: { + return audio_consumer_opensles_plugin_def_t; + } + case PLUGIN_INDEX_AUDIO_PRODUCER: { + return audio_producer_opensles_plugin_def_t; + } + default: { + AUDIO_OPENSLES_DEBUG_ERROR("No plugin at index %d", index); + return tsk_null; + } + } } // // SLES AudioInstance // -typedef struct audio_opensles_instance_s -{ - TSK_DECLARE_OBJECT; - - uint64_t sessionId; - - bool isStarted; - - bool isConsumerPrepared; - bool isConsumerStarted; - bool isProducerPrepared; - bool isProducerStarted; - - bool isSpeakerAvailable; - bool isPlayoutAvailable; - bool isRecordingAvailable; - - SLAudioDevice* device; - SLAudioDeviceCallbackImpl* callback; - - TSK_DECLARE_SAFEOBJ; +typedef struct audio_opensles_instance_s { + TSK_DECLARE_OBJECT; + + uint64_t sessionId; + + bool isStarted; + + bool isConsumerPrepared; + bool isConsumerStarted; + bool isProducerPrepared; + bool isProducerStarted; + + bool isSpeakerAvailable; + bool isPlayoutAvailable; + bool isRecordingAvailable; + + SLAudioDevice* device; + SLAudioDeviceCallbackImpl* callback; + + TSK_DECLARE_SAFEOBJ; } audio_opensles_instance_t; typedef tsk_list_t audio_opensles_instances_L_t; @@ -124,442 +118,442 @@ static audio_opensles_instances_L_t* __audioInstances = tsk_null; static tsk_object_t* audio_opensles_instance_ctor(tsk_object_t * self, va_list * app) { - audio_opensles_instance_t* audioInstance = (audio_opensles_instance_t*)self; - if(audioInstance){ - tsk_safeobj_init(audioInstance); - } - return self; + audio_opensles_instance_t* audioInstance = (audio_opensles_instance_t*)self; + if(audioInstance) { + tsk_safeobj_init(audioInstance); + } + return self; } static tsk_object_t* audio_opensles_instance_dtor(tsk_object_t * self) -{ - AUDIO_OPENSLES_DEBUG_INFO("Audio Instance destroyed"); - audio_opensles_instance_t* audioInstance = (audio_opensles_instance_t*)self; - if(audioInstance){ +{ + AUDIO_OPENSLES_DEBUG_INFO("Audio Instance destroyed"); + audio_opensles_instance_t* audioInstance = (audio_opensles_instance_t*)self; + if(audioInstance) { tsk_safeobj_lock(audioInstance); - if(audioInstance->device){ - audioInstance->device->SetCallback(NULL); - audioInstance->device->Terminate(); - delete audioInstance->device; - audioInstance->device = tsk_null; - } - if(audioInstance->callback){ - delete audioInstance->callback; - audioInstance->callback = tsk_null; - } + if(audioInstance->device) { + audioInstance->device->SetCallback(NULL); + audioInstance->device->Terminate(); + delete audioInstance->device; + audioInstance->device = tsk_null; + } + if(audioInstance->callback) { + delete audioInstance->callback; + audioInstance->callback = tsk_null; + } tsk_safeobj_unlock(audioInstance); - - tsk_safeobj_deinit(audioInstance); - } - return self; + + tsk_safeobj_deinit(audioInstance); + } + return self; } static int audio_opensles_instance_cmp(const tsk_object_t *_ai1, const tsk_object_t *_ai2) { - return ((int)_ai1 - (int)_ai2); + return ((int)_ai1 - (int)_ai2); } -static const tsk_object_def_t audio_opensles_instance_def_s = -{ - sizeof(audio_opensles_instance_t), - audio_opensles_instance_ctor, - audio_opensles_instance_dtor, - audio_opensles_instance_cmp, +static const tsk_object_def_t audio_opensles_instance_def_s = { + sizeof(audio_opensles_instance_t), + audio_opensles_instance_ctor, + audio_opensles_instance_dtor, + audio_opensles_instance_cmp, }; const tsk_object_def_t *audio_opensles_instance_def_t = &audio_opensles_instance_def_s; audio_opensles_instance_handle_t* audio_opensles_instance_create(uint64_t sessionId) { - audio_opensles_instance_t* audioInstance = tsk_null; - - // create list used to hold instances - if(!__audioInstances && !(__audioInstances = tsk_list_create())){ - AUDIO_OPENSLES_DEBUG_ERROR("Failed to create new list"); - return tsk_null; - } - - //= lock the list - tsk_list_lock(__audioInstances); - - // find the instance from the list - const tsk_list_item_t* item; - tsk_list_foreach(item, __audioInstances){ - if(((audio_opensles_instance_t*)item->data)->sessionId == sessionId){ - audioInstance = (audio_opensles_instance_t*)tsk_object_ref(item->data); - break; - } - } - - if(!audioInstance){ - audio_opensles_instance_t* _audioInstance; - if(!(_audioInstance = (audio_opensles_instance_t*)tsk_object_new(&audio_opensles_instance_def_s))){ - AUDIO_OPENSLES_DEBUG_ERROR("Failed to create new audio instance"); - goto done; - } - - if(!(_audioInstance->device = new SLAudioDevice())){ - AUDIO_OPENSLES_DEBUG_ERROR("Failed to create audio device"); - TSK_OBJECT_SAFE_FREE(_audioInstance); - goto done; - } - - if(!(_audioInstance->callback = new SLAudioDeviceCallbackImpl())){ - AUDIO_OPENSLES_DEBUG_ERROR("Failed to create audio transport"); - TSK_OBJECT_SAFE_FREE(_audioInstance); - goto done; - } - if((_audioInstance->device->SetCallback(_audioInstance->callback))){ - AUDIO_OPENSLES_DEBUG_ERROR("AudioDeviceModule::RegisterAudioCallback() failed"); - TSK_OBJECT_SAFE_FREE(_audioInstance); - goto done; - } - - if((_audioInstance->device->Init())){ - AUDIO_OPENSLES_DEBUG_ERROR("AudioDeviceModule::Init() failed"); - TSK_OBJECT_SAFE_FREE(_audioInstance); - goto done; - } - - _audioInstance->sessionId = sessionId; - audioInstance = _audioInstance; - tsk_list_push_back_data(__audioInstances, (void**)&_audioInstance); - } + audio_opensles_instance_t* audioInstance = tsk_null; + + // create list used to hold instances + if(!__audioInstances && !(__audioInstances = tsk_list_create())) { + AUDIO_OPENSLES_DEBUG_ERROR("Failed to create new list"); + return tsk_null; + } + + //= lock the list + tsk_list_lock(__audioInstances); + + // find the instance from the list + const tsk_list_item_t* item; + tsk_list_foreach(item, __audioInstances) { + if(((audio_opensles_instance_t*)item->data)->sessionId == sessionId) { + audioInstance = (audio_opensles_instance_t*)tsk_object_ref(item->data); + break; + } + } + + if(!audioInstance) { + audio_opensles_instance_t* _audioInstance; + if(!(_audioInstance = (audio_opensles_instance_t*)tsk_object_new(&audio_opensles_instance_def_s))) { + AUDIO_OPENSLES_DEBUG_ERROR("Failed to create new audio instance"); + goto done; + } + + if(!(_audioInstance->device = new SLAudioDevice())) { + AUDIO_OPENSLES_DEBUG_ERROR("Failed to create audio device"); + TSK_OBJECT_SAFE_FREE(_audioInstance); + goto done; + } + + if(!(_audioInstance->callback = new SLAudioDeviceCallbackImpl())) { + AUDIO_OPENSLES_DEBUG_ERROR("Failed to create audio transport"); + TSK_OBJECT_SAFE_FREE(_audioInstance); + goto done; + } + if((_audioInstance->device->SetCallback(_audioInstance->callback))) { + AUDIO_OPENSLES_DEBUG_ERROR("AudioDeviceModule::RegisterAudioCallback() failed"); + TSK_OBJECT_SAFE_FREE(_audioInstance); + goto done; + } + + if((_audioInstance->device->Init())) { + AUDIO_OPENSLES_DEBUG_ERROR("AudioDeviceModule::Init() failed"); + TSK_OBJECT_SAFE_FREE(_audioInstance); + goto done; + } + + _audioInstance->sessionId = sessionId; + audioInstance = _audioInstance; + tsk_list_push_back_data(__audioInstances, (void**)&_audioInstance); + } done: - //= unlock the list - tsk_list_unlock(__audioInstances); + //= unlock the list + tsk_list_unlock(__audioInstances); - return audioInstance; + return audioInstance; } int audio_opensles_instance_prepare_consumer(audio_opensles_instance_handle_t* _self, tmedia_consumer_t** _consumer) { - audio_opensles_instance_t* self = (audio_opensles_instance_t*)_self; - const struct audio_consumer_opensles_s* consumer = (const struct audio_consumer_opensles_s*)*_consumer; - if(!self || !self->device || !self->callback || !_consumer || !*_consumer){ - AUDIO_OPENSLES_DEBUG_ERROR("invalid parameter"); - return -1; - } - - if(self->isConsumerPrepared){ - AUDIO_OPENSLES_DEBUG_WARN("Consumer already prepared"); - return 0; - } - - int ret; - bool _bool; - - tsk_safeobj_lock(self); - - self->callback->SetConsumer(consumer); - - if((ret = self->device->SpeakerIsAvailable(&_bool))){ - AUDIO_OPENSLES_DEBUG_ERROR("SpeakerIsAvailable() failed with error code=%d", ret); - } - else{ - if(!_bool){ - AUDIO_OPENSLES_DEBUG_ERROR("SpeakerIsAvailable() returned false"); - } - self->isSpeakerAvailable = _bool; - } - - if((ret = self->device->InitSpeaker())){ - AUDIO_OPENSLES_DEBUG_ERROR("InitSpeaker() failed with error code=%d", ret); - } - else if((ret = self->device->SetSpeakerOn(audio_consumer_opensles_is_speakerOn(consumer)))){ - AUDIO_OPENSLES_DEBUG_ERROR("SetSpeakerOn() failed with error code=%d", ret); - } - - if((ret = self->device->PlayoutIsAvailable(&_bool))){ - AUDIO_OPENSLES_DEBUG_ERROR("PlayoutIsAvailable() failed with error code =%d", ret); - } - else{ - if(!_bool){ - AUDIO_OPENSLES_DEBUG_ERROR("PlayoutIsAvailable() returned false"); - } - self->isPlayoutAvailable = _bool; - } - - if((ret = self->device->SetStereoPlayout(((*_consumer)->audio.in.channels == 2)))){ - AUDIO_OPENSLES_DEBUG_ERROR("SetStereoPlayout(%d==2) failed with error code=%d", (*_consumer)->audio.in.channels, ret); - } - - //if((ret = self->device->SetPlayoutBuffer(AudioDeviceModule::kFixedBufferSize, (*_consumer)->audio.ptime))){ - // AUDIO_OPENSLES_DEBUG_ERROR("SetPlayoutBuffer(%d ms) failed with error code=%d", (*_consumer)->audio.ptime, ret); - //} - // always request 10ms buffers - if((ret = self->device->SetPlayoutBuffer(10))){ - AUDIO_OPENSLES_DEBUG_ERROR("SetPlayoutBuffer(%d ms) failed with error code=%d", 10, ret); - } - - int playoutSampleRate = (*_consumer)->audio.out.rate ? (*_consumer)->audio.out.rate : (*_consumer)->audio.in.rate; - if((ret = self->device->SetPlayoutSampleRate(playoutSampleRate))){ - AUDIO_OPENSLES_DEBUG_ERROR("SetPlayoutSampleRate(%d) failed with error code=%d", playoutSampleRate, ret); - } - - if((ret = self->device->InitPlayout())){ - AUDIO_OPENSLES_DEBUG_ERROR("AudioDeviceModule::InitPlayout() failed with error code = %d", ret); - goto done; - } - - // init output parameters - if((ret = self->device->StereoPlayout(&_bool))){ - AUDIO_OPENSLES_DEBUG_ERROR("StereoPlayout() failed with error code=%d", ret); - } - else{ - (*_consumer)->audio.out.channels = (_bool ? 2 : 1); - } - if((ret = self->device->PlayoutSampleRate(&playoutSampleRate))){ - AUDIO_OPENSLES_DEBUG_ERROR("PlayoutSampleRate() failed with error code=%d", ret); - } - else{ - (*_consumer)->audio.out.rate = playoutSampleRate; - } + audio_opensles_instance_t* self = (audio_opensles_instance_t*)_self; + const struct audio_consumer_opensles_s* consumer = (const struct audio_consumer_opensles_s*)*_consumer; + if(!self || !self->device || !self->callback || !_consumer || !*_consumer) { + AUDIO_OPENSLES_DEBUG_ERROR("invalid parameter"); + return -1; + } + + if(self->isConsumerPrepared) { + AUDIO_OPENSLES_DEBUG_WARN("Consumer already prepared"); + return 0; + } + + int ret; + bool _bool; + + tsk_safeobj_lock(self); + + self->callback->SetConsumer(consumer); + + if((ret = self->device->SpeakerIsAvailable(&_bool))) { + AUDIO_OPENSLES_DEBUG_ERROR("SpeakerIsAvailable() failed with error code=%d", ret); + } + else { + if(!_bool) { + AUDIO_OPENSLES_DEBUG_ERROR("SpeakerIsAvailable() returned false"); + } + self->isSpeakerAvailable = _bool; + } + + if((ret = self->device->InitSpeaker())) { + AUDIO_OPENSLES_DEBUG_ERROR("InitSpeaker() failed with error code=%d", ret); + } + else if((ret = self->device->SetSpeakerOn(audio_consumer_opensles_is_speakerOn(consumer)))) { + AUDIO_OPENSLES_DEBUG_ERROR("SetSpeakerOn() failed with error code=%d", ret); + } + + if((ret = self->device->PlayoutIsAvailable(&_bool))) { + AUDIO_OPENSLES_DEBUG_ERROR("PlayoutIsAvailable() failed with error code =%d", ret); + } + else { + if(!_bool) { + AUDIO_OPENSLES_DEBUG_ERROR("PlayoutIsAvailable() returned false"); + } + self->isPlayoutAvailable = _bool; + } + + if((ret = self->device->SetStereoPlayout(((*_consumer)->audio.in.channels == 2)))) { + AUDIO_OPENSLES_DEBUG_ERROR("SetStereoPlayout(%d==2) failed with error code=%d", (*_consumer)->audio.in.channels, ret); + } + + //if((ret = self->device->SetPlayoutBuffer(AudioDeviceModule::kFixedBufferSize, (*_consumer)->audio.ptime))){ + // AUDIO_OPENSLES_DEBUG_ERROR("SetPlayoutBuffer(%d ms) failed with error code=%d", (*_consumer)->audio.ptime, ret); + //} + // always request 10ms buffers + if((ret = self->device->SetPlayoutBuffer(10))) { + AUDIO_OPENSLES_DEBUG_ERROR("SetPlayoutBuffer(%d ms) failed with error code=%d", 10, ret); + } + + int playoutSampleRate = (*_consumer)->audio.out.rate ? (*_consumer)->audio.out.rate : (*_consumer)->audio.in.rate; + if((ret = self->device->SetPlayoutSampleRate(playoutSampleRate))) { + AUDIO_OPENSLES_DEBUG_ERROR("SetPlayoutSampleRate(%d) failed with error code=%d", playoutSampleRate, ret); + } + + if((ret = self->device->InitPlayout())) { + AUDIO_OPENSLES_DEBUG_ERROR("AudioDeviceModule::InitPlayout() failed with error code = %d", ret); + goto done; + } + + // init output parameters + if((ret = self->device->StereoPlayout(&_bool))) { + AUDIO_OPENSLES_DEBUG_ERROR("StereoPlayout() failed with error code=%d", ret); + } + else { + (*_consumer)->audio.out.channels = (_bool ? 2 : 1); + } + if((ret = self->device->PlayoutSampleRate(&playoutSampleRate))) { + AUDIO_OPENSLES_DEBUG_ERROR("PlayoutSampleRate() failed with error code=%d", ret); + } + else { + (*_consumer)->audio.out.rate = playoutSampleRate; + } done: - tsk_safeobj_unlock(self); + tsk_safeobj_unlock(self); - self->isConsumerPrepared = (ret == 0); + self->isConsumerPrepared = (ret == 0); - return ret; + return ret; } int audio_opensles_instance_prepare_producer(audio_opensles_instance_handle_t* _self, tmedia_producer_t** _producer) { - audio_opensles_instance_t* self = (audio_opensles_instance_t*)_self; - if(!self || !self->device || !self->callback || !_producer || !*_producer){ - AUDIO_OPENSLES_DEBUG_ERROR("invalid parameter"); - return -1; - } - - if(self->isProducerPrepared){ - AUDIO_OPENSLES_DEBUG_WARN("Producer already prepared"); - return 0; - } - - int ret; - bool _bool; - - tsk_safeobj_lock(self); - - self->callback->SetProducer((const struct audio_producer_opensles_s*)*_producer); - - if((ret = self->device->RecordingIsAvailable(&_bool))){ - AUDIO_OPENSLES_DEBUG_ERROR("RecordingIsAvailable() failed with error code =%d", ret); - } - else{ - if(!_bool){ - AUDIO_OPENSLES_DEBUG_ERROR("RecordingIsAvailable() returned false"); - } - self->isRecordingAvailable = _bool; - } - - if((ret = self->device->MicrophoneIsAvailable(&_bool))){ - AUDIO_OPENSLES_DEBUG_ERROR("MicrophoneIsAvailable() failed with error code =%d", ret); - } - else{ - if(!_bool){ - AUDIO_OPENSLES_DEBUG_ERROR("MicrophoneIsAvailable() returned false"); - } - else{ - if((ret = self->device->InitMicrophone())){ - AUDIO_OPENSLES_DEBUG_ERROR("InitMicrophone() failed with error code =%d", ret); - } - } - } - - if((ret = self->device->SetStereoRecording(((*_producer)->audio.channels == 2)))){ - AUDIO_OPENSLES_DEBUG_ERROR("SetStereoRecording(%d==2) failed with error code=%d", (*_producer)->audio.channels, ret); - } - - int recordingSampleRate = (*_producer)->audio.rate; - if((ret = self->device->SetRecordingSampleRate(recordingSampleRate))){ - AUDIO_OPENSLES_DEBUG_ERROR("SetRecordingSampleRate(%d) failed with error code=%d", recordingSampleRate, ret); - } - - if((ret = self->device->InitRecording())){ - AUDIO_OPENSLES_DEBUG_ERROR("AudioDeviceModule::InitRecording() failed with error code = %d", ret); - goto done; - } - - // init output parameters - if((ret = self->device->StereoRecording(&_bool))){ - AUDIO_OPENSLES_DEBUG_ERROR("StereoRecording() failed with error code=%d", ret); - } - else{ - (*_producer)->audio.channels = (_bool ? 2 : 1); - } - if((ret = self->device->RecordingSampleRate(&recordingSampleRate))){ - AUDIO_OPENSLES_DEBUG_ERROR("RecordingSampleRate() failed with error code=%d", ret); - } - else{ - (*_producer)->audio.rate = recordingSampleRate; - } + audio_opensles_instance_t* self = (audio_opensles_instance_t*)_self; + if(!self || !self->device || !self->callback || !_producer || !*_producer) { + AUDIO_OPENSLES_DEBUG_ERROR("invalid parameter"); + return -1; + } + + if(self->isProducerPrepared) { + AUDIO_OPENSLES_DEBUG_WARN("Producer already prepared"); + return 0; + } + + int ret; + bool _bool; + + tsk_safeobj_lock(self); + + self->callback->SetProducer((const struct audio_producer_opensles_s*)*_producer); + + if((ret = self->device->RecordingIsAvailable(&_bool))) { + AUDIO_OPENSLES_DEBUG_ERROR("RecordingIsAvailable() failed with error code =%d", ret); + } + else { + if(!_bool) { + AUDIO_OPENSLES_DEBUG_ERROR("RecordingIsAvailable() returned false"); + } + self->isRecordingAvailable = _bool; + } + + if((ret = self->device->MicrophoneIsAvailable(&_bool))) { + AUDIO_OPENSLES_DEBUG_ERROR("MicrophoneIsAvailable() failed with error code =%d", ret); + } + else { + if(!_bool) { + AUDIO_OPENSLES_DEBUG_ERROR("MicrophoneIsAvailable() returned false"); + } + else { + if((ret = self->device->InitMicrophone())) { + AUDIO_OPENSLES_DEBUG_ERROR("InitMicrophone() failed with error code =%d", ret); + } + } + } + + if((ret = self->device->SetStereoRecording(((*_producer)->audio.channels == 2)))) { + AUDIO_OPENSLES_DEBUG_ERROR("SetStereoRecording(%d==2) failed with error code=%d", (*_producer)->audio.channels, ret); + } + + int recordingSampleRate = (*_producer)->audio.rate; + if((ret = self->device->SetRecordingSampleRate(recordingSampleRate))) { + AUDIO_OPENSLES_DEBUG_ERROR("SetRecordingSampleRate(%d) failed with error code=%d", recordingSampleRate, ret); + } + + if((ret = self->device->InitRecording())) { + AUDIO_OPENSLES_DEBUG_ERROR("AudioDeviceModule::InitRecording() failed with error code = %d", ret); + goto done; + } + + // init output parameters + if((ret = self->device->StereoRecording(&_bool))) { + AUDIO_OPENSLES_DEBUG_ERROR("StereoRecording() failed with error code=%d", ret); + } + else { + (*_producer)->audio.channels = (_bool ? 2 : 1); + } + if((ret = self->device->RecordingSampleRate(&recordingSampleRate))) { + AUDIO_OPENSLES_DEBUG_ERROR("RecordingSampleRate() failed with error code=%d", ret); + } + else { + (*_producer)->audio.rate = recordingSampleRate; + } done: - tsk_safeobj_unlock(self); + tsk_safeobj_unlock(self); - self->isProducerPrepared = (ret == 0); + self->isProducerPrepared = (ret == 0); - return ret; + return ret; } int audio_opensles_instance_start_consumer(audio_opensles_instance_handle_t* _self) { - audio_opensles_instance_t* self = (audio_opensles_instance_t*)_self; - if(!self || !self->device || !self->callback){ - AUDIO_OPENSLES_DEBUG_ERROR("invalid parameter"); - return -1; - } - - tsk_safeobj_lock(self); - if(!self->isConsumerPrepared){ - AUDIO_OPENSLES_DEBUG_ERROR("Consumer not prepared"); - goto done; - } - - if(self->isConsumerStarted){ - AUDIO_OPENSLES_DEBUG_WARN("Consumer already started"); - goto done; - } - - if(self->isPlayoutAvailable){ - int ret; - if((ret = self->device->StartPlayout())){ - AUDIO_OPENSLES_DEBUG_ERROR("StartPlayout() failed with error code = %d", ret); - } - - self->isConsumerStarted = self->device->Playing(); - AUDIO_OPENSLES_DEBUG_INFO("isPlaying=%s", (self->isConsumerPrepared ? "true" : "false")); - } + audio_opensles_instance_t* self = (audio_opensles_instance_t*)_self; + if(!self || !self->device || !self->callback) { + AUDIO_OPENSLES_DEBUG_ERROR("invalid parameter"); + return -1; + } + + tsk_safeobj_lock(self); + if(!self->isConsumerPrepared) { + AUDIO_OPENSLES_DEBUG_ERROR("Consumer not prepared"); + goto done; + } + + if(self->isConsumerStarted) { + AUDIO_OPENSLES_DEBUG_WARN("Consumer already started"); + goto done; + } + + if(self->isPlayoutAvailable) { + int ret; + if((ret = self->device->StartPlayout())) { + AUDIO_OPENSLES_DEBUG_ERROR("StartPlayout() failed with error code = %d", ret); + } + + self->isConsumerStarted = self->device->Playing(); + AUDIO_OPENSLES_DEBUG_INFO("isPlaying=%s", (self->isConsumerPrepared ? "true" : "false")); + } done: - tsk_safeobj_unlock(self); - return (self->isConsumerStarted ? 0 : -1); + tsk_safeobj_unlock(self); + return (self->isConsumerStarted ? 0 : -1); } int audio_opensles_instance_start_producer(audio_opensles_instance_handle_t* _self) { - audio_opensles_instance_t* self = (audio_opensles_instance_t*)_self; - if(!self || !self->device || !self->callback){ - AUDIO_OPENSLES_DEBUG_ERROR("invalid parameter"); - return -1; - } - - tsk_safeobj_lock(self); - if(!self->isProducerPrepared){ - AUDIO_OPENSLES_DEBUG_ERROR("Producer not prepared"); - goto done; - } - - if(self->isProducerStarted){ - AUDIO_OPENSLES_DEBUG_WARN("Consumer already started"); - goto done; - } - - if(self->isRecordingAvailable){ - int ret; - if((ret = self->device->StartRecording())){ - AUDIO_OPENSLES_DEBUG_ERROR("StartRecording() failed with error code = %d", ret); - } - - self->isProducerStarted = self->device->Recording(); - AUDIO_OPENSLES_DEBUG_INFO("isRecording=%s", (self->isProducerStarted ? "true" : "false")); - } + audio_opensles_instance_t* self = (audio_opensles_instance_t*)_self; + if(!self || !self->device || !self->callback) { + AUDIO_OPENSLES_DEBUG_ERROR("invalid parameter"); + return -1; + } + + tsk_safeobj_lock(self); + if(!self->isProducerPrepared) { + AUDIO_OPENSLES_DEBUG_ERROR("Producer not prepared"); + goto done; + } + + if(self->isProducerStarted) { + AUDIO_OPENSLES_DEBUG_WARN("Consumer already started"); + goto done; + } + + if(self->isRecordingAvailable) { + int ret; + if((ret = self->device->StartRecording())) { + AUDIO_OPENSLES_DEBUG_ERROR("StartRecording() failed with error code = %d", ret); + } + + self->isProducerStarted = self->device->Recording(); + AUDIO_OPENSLES_DEBUG_INFO("isRecording=%s", (self->isProducerStarted ? "true" : "false")); + } done: - tsk_safeobj_unlock(self); - return (self->isProducerStarted ? 0 : -1); + tsk_safeobj_unlock(self); + return (self->isProducerStarted ? 0 : -1); } int audio_opensles_instance_stop_consumer(audio_opensles_instance_handle_t* _self) { - audio_opensles_instance_t* self = (audio_opensles_instance_t*)_self; - if(!self || !self->device || !self->callback){ - AUDIO_OPENSLES_DEBUG_ERROR("invalid parameter"); - return -1; - } - - tsk_safeobj_lock(self); - - if(!self->isConsumerStarted){ - goto done; - } - - int ret; - if((ret = self->device->StopPlayout())){ - AUDIO_OPENSLES_DEBUG_ERROR("StopPlayout() failed with error code = %d", ret); - } - else{ - self->isConsumerStarted = self->device->Playing(); - self->isConsumerPrepared = false; - } + audio_opensles_instance_t* self = (audio_opensles_instance_t*)_self; + if(!self || !self->device || !self->callback) { + AUDIO_OPENSLES_DEBUG_ERROR("invalid parameter"); + return -1; + } + + tsk_safeobj_lock(self); + + if(!self->isConsumerStarted) { + goto done; + } + + int ret; + if((ret = self->device->StopPlayout())) { + AUDIO_OPENSLES_DEBUG_ERROR("StopPlayout() failed with error code = %d", ret); + } + else { + self->isConsumerStarted = self->device->Playing(); + self->isConsumerPrepared = false; + } done: - tsk_safeobj_unlock(self); - return (self->isConsumerStarted ? -1 : 0); + tsk_safeobj_unlock(self); + return (self->isConsumerStarted ? -1 : 0); } int audio_opensles_instance_stop_producer(audio_opensles_instance_handle_t* _self) { - audio_opensles_instance_t* self = (audio_opensles_instance_t*)_self; - if(!self || !self->device || !self->callback){ - AUDIO_OPENSLES_DEBUG_ERROR("invalid parameter"); - return -1; - } - - tsk_safeobj_lock(self); - - if(!self->isProducerStarted){ - goto done; - } - - int ret; - if((ret = self->device->StopRecording())){ - AUDIO_OPENSLES_DEBUG_ERROR("StopRecording() failed with error code = %d", ret); - } - else{ - self->isProducerStarted = self->device->Recording(); - self->isProducerPrepared = false; - } + audio_opensles_instance_t* self = (audio_opensles_instance_t*)_self; + if(!self || !self->device || !self->callback) { + AUDIO_OPENSLES_DEBUG_ERROR("invalid parameter"); + return -1; + } + + tsk_safeobj_lock(self); + + if(!self->isProducerStarted) { + goto done; + } + + int ret; + if((ret = self->device->StopRecording())) { + AUDIO_OPENSLES_DEBUG_ERROR("StopRecording() failed with error code = %d", ret); + } + else { + self->isProducerStarted = self->device->Recording(); + self->isProducerPrepared = false; + } done: - tsk_safeobj_unlock(self); - return (self->isProducerStarted ? -1 : 0); + tsk_safeobj_unlock(self); + return (self->isProducerStarted ? -1 : 0); } int audio_opensles_instance_set_speakerOn(audio_opensles_instance_handle_t* _self, bool speakerOn) { - audio_opensles_instance_t* self = (audio_opensles_instance_t*)_self; - if(!self || !self->device ){ - AUDIO_OPENSLES_DEBUG_ERROR("Invalid parameter"); - return -1; - } - return self->device->SetSpeakerOn(speakerOn); + audio_opensles_instance_t* self = (audio_opensles_instance_t*)_self; + if(!self || !self->device ) { + AUDIO_OPENSLES_DEBUG_ERROR("Invalid parameter"); + return -1; + } + return self->device->SetSpeakerOn(speakerOn); } int audio_opensles_instance_set_microphone_volume(audio_opensles_instance_handle_t* _self, int32_t volume) { - audio_opensles_instance_t* self = (audio_opensles_instance_t*)_self; - if(!self || !self->device ){ - AUDIO_OPENSLES_DEBUG_ERROR("Invalid parameter"); - return -1; - } - return self->device->SetMicrophoneVolume(volume); + audio_opensles_instance_t* self = (audio_opensles_instance_t*)_self; + if(!self || !self->device ) { + AUDIO_OPENSLES_DEBUG_ERROR("Invalid parameter"); + return -1; + } + return self->device->SetMicrophoneVolume(volume); } -int audio_opensles_instance_destroy(audio_opensles_instance_handle_t** _self){ - if(!_self || !*_self){ - AUDIO_OPENSLES_DEBUG_ERROR("Invalid parameter"); - return -1; - } - tsk_list_lock(__audioInstances); - if(tsk_object_get_refcount(*_self)==1){ - tsk_list_remove_item_by_data(__audioInstances, *_self); - } - else { - tsk_object_unref(*_self); - } - tsk_list_unlock(__audioInstances); - *_self = tsk_null; - return 0; +int audio_opensles_instance_destroy(audio_opensles_instance_handle_t** _self) +{ + if(!_self || !*_self) { + AUDIO_OPENSLES_DEBUG_ERROR("Invalid parameter"); + return -1; + } + tsk_list_lock(__audioInstances); + if(tsk_object_get_refcount(*_self)==1) { + tsk_list_remove_item_by_data(__audioInstances, *_self); + } + else { + tsk_object_unref(*_self); + } + tsk_list_unlock(__audioInstances); + *_self = tsk_null; + return 0; } diff --git a/plugins/audio_opensles/audio_opensles.h b/plugins/audio_opensles/audio_opensles.h index 7837509..e96966e 100755 --- a/plugins/audio_opensles/audio_opensles.h +++ b/plugins/audio_opensles/audio_opensles.h @@ -1,17 +1,17 @@ /* Copyright (C) 2012 Doubango Telecom <http://www.doubango.org> -* +* * This file is part of Open Source Doubango Framework. * * DOUBANGO 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 3 of the License, or * (at your option) any later version. -* +* * DOUBANGO 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 DOUBANGO. */ diff --git a/plugins/audio_opensles/audio_opensles_config.h b/plugins/audio_opensles/audio_opensles_config.h index a495608..6967492 100755 --- a/plugins/audio_opensles/audio_opensles_config.h +++ b/plugins/audio_opensles/audio_opensles_config.h @@ -1,17 +1,17 @@ /* Copyright (C) 2012 Doubango Telecom <http://www.doubango.org> -* +* * This file is part of Open Source Doubango Framework. * * DOUBANGO 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 3 of the License, or * (at your option) any later version. -* +* * DOUBANGO 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 DOUBANGO. */ @@ -66,18 +66,18 @@ # define AUDIO_OPENSLES_GEXTERN extern #endif -// Guards against C++ name mangling +// Guards against C++ name mangling #ifdef __cplusplus # define AUDIO_OPENSLES_BEGIN_DECLS extern "C" { # define AUDIO_OPENSLES_END_DECLS } #else -# define AUDIO_OPENSLES_BEGIN_DECLS +# define AUDIO_OPENSLES_BEGIN_DECLS # define AUDIO_OPENSLES_END_DECLS #endif #ifdef _MSC_VER #if HAVE_FFMPEG // FFMPeg warnings (treated as errors) -# pragma warning (disable:4244) +# pragma warning (disable:4244) #endif # define inline __inline # define _CRT_SECURE_NO_WARNINGS @@ -94,7 +94,7 @@ #endif #if HAVE_CONFIG_H - #include "../config.h" +#include "../config.h" #endif #if AUDIO_OPENSLES_UNDER_ANDROID diff --git a/plugins/audio_opensles/audio_opensles_consumer.cxx b/plugins/audio_opensles/audio_opensles_consumer.cxx index 57acd7f..5585316 100755 --- a/plugins/audio_opensles/audio_opensles_consumer.cxx +++ b/plugins/audio_opensles/audio_opensles_consumer.cxx @@ -1,17 +1,17 @@ /* Copyright (C) 2012 Doubango Telecom <http://www.doubango.org> -* +* * This file is part of Open Source Doubango Framework. * * DOUBANGO 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 3 of the License, or * (at your option) any later version. -* +* * DOUBANGO 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 DOUBANGO. */ @@ -25,172 +25,173 @@ #include "tsk_memory.h" #include "tsk_debug.h" -typedef struct audio_consumer_opensles_s -{ - TDAV_DECLARE_CONSUMER_AUDIO; - audio_opensles_instance_handle_t* audioInstHandle; - bool isSpeakerOn; - struct{ - void* ptr; - bool isFull; - int size; - int index; - } buffer; +typedef struct audio_consumer_opensles_s { + TDAV_DECLARE_CONSUMER_AUDIO; + audio_opensles_instance_handle_t* audioInstHandle; + bool isSpeakerOn; + struct { + void* ptr; + bool isFull; + int size; + int index; + } buffer; } audio_consumer_opensles_t; int audio_consumer_opensles_get_data_10ms(const audio_consumer_opensles_t* _self, void* audioSamples, int nSamples, int nBytesPerSample, int nChannels, int samplesPerSec, uint32_t &nSamplesOut) { - nSamplesOut = 0; - if(!_self || !audioSamples || !nSamples){ - AUDIO_OPENSLES_DEBUG_ERROR("Invalid parameter"); - return -1; - } - if((nSamples != (samplesPerSec / 100))){ - AUDIO_OPENSLES_DEBUG_ERROR("Not producing 10ms samples (nSamples=%d, samplesPerSec=%d)", nSamples, samplesPerSec); - return -2; - } - if((nBytesPerSample != (TMEDIA_CONSUMER(_self)->audio.bits_per_sample >> 3))){ - AUDIO_OPENSLES_DEBUG_ERROR("%d not valid bytes/samples", nBytesPerSample); - return -3; - } - if((nChannels != TMEDIA_CONSUMER(_self)->audio.out.channels)){ - AUDIO_OPENSLES_DEBUG_ERROR("Playout - %d not the expected number of channels but should be %d", nChannels, TMEDIA_CONSUMER(_self)->audio.out.channels); - return -4; - } - - audio_consumer_opensles_t* self = const_cast<audio_consumer_opensles_t*>(_self); - - if(self->buffer.index == self->buffer.size){ - if((tdav_consumer_audio_get(TDAV_CONSUMER_AUDIO(self), self->buffer.ptr, self->buffer.size)) != self->buffer.size){ - nSamplesOut = 0; - self->buffer.index = self->buffer.size; - return 0; - } - self->buffer.index = 0; - tdav_consumer_audio_tick(TDAV_CONSUMER_AUDIO(self)); - } - - int nSamplesInBits = (nSamples * nBytesPerSample); - if(_self->buffer.index + nSamplesInBits <= _self->buffer.size){ - memcpy(audioSamples, (((uint8_t*)self->buffer.ptr) + self->buffer.index), nSamplesInBits); - } - self->buffer.index += nSamplesInBits; - TSK_CLAMP(0, self->buffer.index, self->buffer.size); - nSamplesOut = nSamples; - - return 0; + nSamplesOut = 0; + if(!_self || !audioSamples || !nSamples) { + AUDIO_OPENSLES_DEBUG_ERROR("Invalid parameter"); + return -1; + } + if((nSamples != (samplesPerSec / 100))) { + AUDIO_OPENSLES_DEBUG_ERROR("Not producing 10ms samples (nSamples=%d, samplesPerSec=%d)", nSamples, samplesPerSec); + return -2; + } + if((nBytesPerSample != (TMEDIA_CONSUMER(_self)->audio.bits_per_sample >> 3))) { + AUDIO_OPENSLES_DEBUG_ERROR("%d not valid bytes/samples", nBytesPerSample); + return -3; + } + if((nChannels != TMEDIA_CONSUMER(_self)->audio.out.channels)) { + AUDIO_OPENSLES_DEBUG_ERROR("Playout - %d not the expected number of channels but should be %d", nChannels, TMEDIA_CONSUMER(_self)->audio.out.channels); + return -4; + } + + audio_consumer_opensles_t* self = const_cast<audio_consumer_opensles_t*>(_self); + + if(self->buffer.index == self->buffer.size) { + if((tdav_consumer_audio_get(TDAV_CONSUMER_AUDIO(self), self->buffer.ptr, self->buffer.size)) != self->buffer.size) { + nSamplesOut = 0; + self->buffer.index = self->buffer.size; + return 0; + } + self->buffer.index = 0; + tdav_consumer_audio_tick(TDAV_CONSUMER_AUDIO(self)); + } + + int nSamplesInBits = (nSamples * nBytesPerSample); + if(_self->buffer.index + nSamplesInBits <= _self->buffer.size) { + memcpy(audioSamples, (((uint8_t*)self->buffer.ptr) + self->buffer.index), nSamplesInBits); + } + self->buffer.index += nSamplesInBits; + TSK_CLAMP(0, self->buffer.index, self->buffer.size); + nSamplesOut = nSamples; + + return 0; } bool audio_consumer_opensles_is_speakerOn(const audio_consumer_opensles_t* self) { - if(!self){ - AUDIO_OPENSLES_DEBUG_ERROR("Invalid parameter"); - return false; - } - return self->isSpeakerOn; + if(!self) { + AUDIO_OPENSLES_DEBUG_ERROR("Invalid parameter"); + return false; + } + return self->isSpeakerOn; } /* ============ Media Consumer Interface ================= */ static int audio_consumer_opensles_set(tmedia_consumer_t* _self, const tmedia_param_t* param) { - audio_consumer_opensles_t* self = (audio_consumer_opensles_t*)_self; - int ret = tdav_consumer_audio_set(TDAV_CONSUMER_AUDIO(self), param); - - if(ret == 0){ - if(tsk_striequals(param->key, "volume")){ - - } - else if(tsk_striequals(param->key, "speaker-on")){ - self->isSpeakerOn = (TSK_TO_INT32((uint8_t*)param->value) != 0); - if(self->audioInstHandle){ - return audio_opensles_instance_set_speakerOn(self->audioInstHandle, self->isSpeakerOn); - } - else return 0; // will be set when instance is initialized - } - } - - return ret; + audio_consumer_opensles_t* self = (audio_consumer_opensles_t*)_self; + int ret = tdav_consumer_audio_set(TDAV_CONSUMER_AUDIO(self), param); + + if(ret == 0) { + if(tsk_striequals(param->key, "volume")) { + + } + else if(tsk_striequals(param->key, "speaker-on")) { + self->isSpeakerOn = (TSK_TO_INT32((uint8_t*)param->value) != 0); + if(self->audioInstHandle) { + return audio_opensles_instance_set_speakerOn(self->audioInstHandle, self->isSpeakerOn); + } + else { + return 0; // will be set when instance is initialized + } + } + } + + return ret; } static int audio_consumer_opensles_prepare(tmedia_consumer_t* _self, const tmedia_codec_t* codec) { - audio_consumer_opensles_t* self = (audio_consumer_opensles_t*)_self; - if(!self){ - AUDIO_OPENSLES_DEBUG_ERROR("Invalid parameter"); - return -1; - } - - // create audio instance - if(!(self->audioInstHandle = audio_opensles_instance_create(TMEDIA_CONSUMER(self)->session_id))){ - AUDIO_OPENSLES_DEBUG_ERROR("Failed to create audio instance handle"); - return -1; - } - - // initialize input parameters from the codec information - TMEDIA_CONSUMER(self)->audio.ptime = TMEDIA_CODEC_PTIME_AUDIO_DECODING(codec); - TMEDIA_CONSUMER(self)->audio.in.channels = TMEDIA_CODEC_CHANNELS_AUDIO_DECODING(codec); - TMEDIA_CONSUMER(self)->audio.in.rate = TMEDIA_CODEC_RATE_DECODING(codec); - - AUDIO_OPENSLES_DEBUG_INFO("audio_consumer_opensles_prepare(channels=%d, rate=%d, ptime=%d)", codec->plugin->audio.channels, codec->plugin->rate, codec->plugin->audio.ptime); - - // prepare playout device and update output parameters - int ret = audio_opensles_instance_prepare_consumer(self->audioInstHandle, &_self); - - // now that the producer is prepared we can initialize internal buffer using device caps - if(ret == 0){ - // allocate buffer - int xsize = ((TMEDIA_CONSUMER(self)->audio.ptime * TMEDIA_CONSUMER(self)->audio.out.rate) / 1000) * (TMEDIA_CONSUMER(self)->audio.bits_per_sample >> 3); - if(!(self->buffer.ptr = tsk_realloc(self->buffer.ptr, xsize))){ - AUDIO_OPENSLES_DEBUG_ERROR("Failed to allocate buffer with size = %d", xsize); - self->buffer.size = 0; - return -1; - } - memset(self->buffer.ptr, 0, xsize); - self->buffer.size = xsize; - self->buffer.index = 0; - self->buffer.isFull = false; - } - return ret; + audio_consumer_opensles_t* self = (audio_consumer_opensles_t*)_self; + if(!self) { + AUDIO_OPENSLES_DEBUG_ERROR("Invalid parameter"); + return -1; + } + + // create audio instance + if(!(self->audioInstHandle = audio_opensles_instance_create(TMEDIA_CONSUMER(self)->session_id))) { + AUDIO_OPENSLES_DEBUG_ERROR("Failed to create audio instance handle"); + return -1; + } + + // initialize input parameters from the codec information + TMEDIA_CONSUMER(self)->audio.ptime = TMEDIA_CODEC_PTIME_AUDIO_DECODING(codec); + TMEDIA_CONSUMER(self)->audio.in.channels = TMEDIA_CODEC_CHANNELS_AUDIO_DECODING(codec); + TMEDIA_CONSUMER(self)->audio.in.rate = TMEDIA_CODEC_RATE_DECODING(codec); + + AUDIO_OPENSLES_DEBUG_INFO("audio_consumer_opensles_prepare(channels=%d, rate=%d, ptime=%d)", codec->plugin->audio.channels, codec->plugin->rate, codec->plugin->audio.ptime); + + // prepare playout device and update output parameters + int ret = audio_opensles_instance_prepare_consumer(self->audioInstHandle, &_self); + + // now that the producer is prepared we can initialize internal buffer using device caps + if(ret == 0) { + // allocate buffer + int xsize = ((TMEDIA_CONSUMER(self)->audio.ptime * TMEDIA_CONSUMER(self)->audio.out.rate) / 1000) * (TMEDIA_CONSUMER(self)->audio.bits_per_sample >> 3); + if(!(self->buffer.ptr = tsk_realloc(self->buffer.ptr, xsize))) { + AUDIO_OPENSLES_DEBUG_ERROR("Failed to allocate buffer with size = %d", xsize); + self->buffer.size = 0; + return -1; + } + memset(self->buffer.ptr, 0, xsize); + self->buffer.size = xsize; + self->buffer.index = 0; + self->buffer.isFull = false; + } + return ret; } static int audio_consumer_opensles_start(tmedia_consumer_t* _self) { - audio_consumer_opensles_t* self = (audio_consumer_opensles_t*)_self; - if(!self){ - AUDIO_OPENSLES_DEBUG_ERROR("Invalid parameter"); - return -1; - } + audio_consumer_opensles_t* self = (audio_consumer_opensles_t*)_self; + if(!self) { + AUDIO_OPENSLES_DEBUG_ERROR("Invalid parameter"); + return -1; + } - return audio_opensles_instance_start_consumer(self->audioInstHandle); + return audio_opensles_instance_start_consumer(self->audioInstHandle); } static int audio_consumer_opensles_consume(tmedia_consumer_t* _self, const void* data, tsk_size_t data_size, const tsk_object_t* proto_hdr) { - audio_consumer_opensles_t* self = (audio_consumer_opensles_t*)_self; - if(!self || !data || !data_size){ - AUDIO_OPENSLES_DEBUG_ERROR("1Invalid parameter"); - return -1; - } - /* buffer is already decoded */ - return tdav_consumer_audio_put(TDAV_CONSUMER_AUDIO(self), data, data_size, proto_hdr); + audio_consumer_opensles_t* self = (audio_consumer_opensles_t*)_self; + if(!self || !data || !data_size) { + AUDIO_OPENSLES_DEBUG_ERROR("1Invalid parameter"); + return -1; + } + /* buffer is already decoded */ + return tdav_consumer_audio_put(TDAV_CONSUMER_AUDIO(self), data, data_size, proto_hdr); } static int audio_consumer_opensles_pause(tmedia_consumer_t* self) { - return 0; + return 0; } static int audio_consumer_opensles_stop(tmedia_consumer_t* _self) { - audio_consumer_opensles_t* self = (audio_consumer_opensles_t*)_self; - if(!self){ - AUDIO_OPENSLES_DEBUG_ERROR("Invalid parameter"); - return -1; - } + audio_consumer_opensles_t* self = (audio_consumer_opensles_t*)_self; + if(!self) { + AUDIO_OPENSLES_DEBUG_ERROR("Invalid parameter"); + return -1; + } - return audio_opensles_instance_stop_consumer(self->audioInstHandle); + return audio_opensles_instance_stop_consumer(self->audioInstHandle); } @@ -200,54 +201,52 @@ static int audio_consumer_opensles_stop(tmedia_consumer_t* _self) /* constructor */ static tsk_object_t* audio_consumer_opensles_ctor(tsk_object_t *_self, va_list * app) { - audio_consumer_opensles_t *self = (audio_consumer_opensles_t *)_self; - if(self){ - /* init base */ - tdav_consumer_audio_init(TDAV_CONSUMER_AUDIO(self)); - /* init self */ - - } - return self; + audio_consumer_opensles_t *self = (audio_consumer_opensles_t *)_self; + if(self) { + /* init base */ + tdav_consumer_audio_init(TDAV_CONSUMER_AUDIO(self)); + /* init self */ + + } + return self; } /* destructor */ static tsk_object_t* audio_consumer_opensles_dtor(tsk_object_t *_self) -{ - audio_consumer_opensles_t *self = (audio_consumer_opensles_t *)_self; - if(self){ - /* stop */ - audio_consumer_opensles_stop(TMEDIA_CONSUMER(self)); - /* deinit self */ - if(self->audioInstHandle){ - audio_opensles_instance_destroy(&self->audioInstHandle); - } - TSK_FREE(self->buffer.ptr); - /* deinit base */ - tdav_consumer_audio_deinit(TDAV_CONSUMER_AUDIO(self)); - } - - return self; +{ + audio_consumer_opensles_t *self = (audio_consumer_opensles_t *)_self; + if(self) { + /* stop */ + audio_consumer_opensles_stop(TMEDIA_CONSUMER(self)); + /* deinit self */ + if(self->audioInstHandle) { + audio_opensles_instance_destroy(&self->audioInstHandle); + } + TSK_FREE(self->buffer.ptr); + /* deinit base */ + tdav_consumer_audio_deinit(TDAV_CONSUMER_AUDIO(self)); + } + + return self; } /* object definition */ -static const tsk_object_def_t audio_consumer_opensles_def_s = -{ - sizeof(audio_consumer_opensles_t), - audio_consumer_opensles_ctor, - audio_consumer_opensles_dtor, - tdav_consumer_audio_cmp, +static const tsk_object_def_t audio_consumer_opensles_def_s = { + sizeof(audio_consumer_opensles_t), + audio_consumer_opensles_ctor, + audio_consumer_opensles_dtor, + tdav_consumer_audio_cmp, }; /* plugin definition*/ -static const tmedia_consumer_plugin_def_t audio_consumer_opensles_plugin_def_s = -{ - &audio_consumer_opensles_def_s, - - tmedia_audio, - "SLES audio consumer", - - audio_consumer_opensles_set, - audio_consumer_opensles_prepare, - audio_consumer_opensles_start, - audio_consumer_opensles_consume, - audio_consumer_opensles_pause, - audio_consumer_opensles_stop +static const tmedia_consumer_plugin_def_t audio_consumer_opensles_plugin_def_s = { + &audio_consumer_opensles_def_s, + + tmedia_audio, + "SLES audio consumer", + + audio_consumer_opensles_set, + audio_consumer_opensles_prepare, + audio_consumer_opensles_start, + audio_consumer_opensles_consume, + audio_consumer_opensles_pause, + audio_consumer_opensles_stop }; const tmedia_consumer_plugin_def_t *audio_consumer_opensles_plugin_def_t = &audio_consumer_opensles_plugin_def_s; diff --git a/plugins/audio_opensles/audio_opensles_consumer.h b/plugins/audio_opensles/audio_opensles_consumer.h index 1702db6..786813b 100755 --- a/plugins/audio_opensles/audio_opensles_consumer.h +++ b/plugins/audio_opensles/audio_opensles_consumer.h @@ -1,17 +1,17 @@ /* Copyright (C) 2012 Doubango Telecom <http://www.doubango.org> -* +* * This file is part of Open Source Doubango Framework. * * DOUBANGO 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 3 of the License, or * (at your option) any later version. -* +* * DOUBANGO 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 DOUBANGO. */ @@ -22,7 +22,7 @@ AUDIO_OPENSLES_BEGIN_DECLS -extern const struct tmedia_consumer_plugin_def_s *audio_consumer_opensles_plugin_def_t; +extern const struct tmedia_consumer_plugin_def_s *audio_consumer_opensles_plugin_def_t; int audio_consumer_opensles_get_data_10ms(const struct audio_consumer_opensles_s* self, void* audioSamples, int nSamples, int nBytesPerSample, int nChannels, int samplesPerSec, uint32_t &nSamplesOut); bool audio_consumer_opensles_is_speakerOn(const struct audio_consumer_opensles_s* self); diff --git a/plugins/audio_opensles/audio_opensles_device.cxx b/plugins/audio_opensles/audio_opensles_device.cxx index 3c06bfc..e6fff79 100755 --- a/plugins/audio_opensles/audio_opensles_device.cxx +++ b/plugins/audio_opensles/audio_opensles_device.cxx @@ -23,64 +23,77 @@ #define CHECK_MICROPHONE_NOT_INITIALIZED() CHECK_FALSE(m_bMicrophoneInitialized, "Microphone initialized") #if AUDIO_OPENSLES_UNDER_ANDROID -static inline SLuint32 SL_SAMPLING_RATE(int RATE_INT){ - switch(RATE_INT){ - case 8000: return SL_SAMPLINGRATE_8; - case 11025: return SL_SAMPLINGRATE_11_025; - default:case 16000: return SL_SAMPLINGRATE_16; - case 22050: return SL_SAMPLINGRATE_22_05; - case 24000: return SL_SAMPLINGRATE_24; - case 32000: return SL_SAMPLINGRATE_32; - case 44100: return SL_SAMPLINGRATE_44_1; - case 64000: return SL_SAMPLINGRATE_64; - case 88200: return SL_SAMPLINGRATE_88_2; - case 96000: return SL_SAMPLINGRATE_96; - case 192000: return SL_SAMPLINGRATE_192; - } +static inline SLuint32 SL_SAMPLING_RATE(int RATE_INT) +{ + switch(RATE_INT) { + case 8000: + return SL_SAMPLINGRATE_8; + case 11025: + return SL_SAMPLINGRATE_11_025; + default: + case 16000: + return SL_SAMPLINGRATE_16; + case 22050: + return SL_SAMPLINGRATE_22_05; + case 24000: + return SL_SAMPLINGRATE_24; + case 32000: + return SL_SAMPLINGRATE_32; + case 44100: + return SL_SAMPLINGRATE_44_1; + case 64000: + return SL_SAMPLINGRATE_64; + case 88200: + return SL_SAMPLINGRATE_88_2; + case 96000: + return SL_SAMPLINGRATE_96; + case 192000: + return SL_SAMPLINGRATE_192; + } } #endif SLAudioDevice::SLAudioDevice(const SLAudioDeviceCallback* pCallback): #if AUDIO_OPENSLES_UNDER_ANDROID -m_slEngineObject(NULL), -m_slPlayer(NULL), -m_slEngine(NULL), -m_slPlayerPlay(NULL), -m_slPlayerSimpleBufferQueue(NULL), -m_slOutputMixObject(NULL), -m_slSpeakerVolume(NULL), -m_slRecorder(NULL), -m_slRecorderRecord(NULL), -m_slAudioIODeviceCapabilities(NULL), -m_slRecorderSimpleBufferQueue(NULL), -m_slMicVolume(NULL), -_playQueueSeq(0), -_recCurrentSeq(0), -_recBufferTotalSize(0), -_recQueueSeq(0), + m_slEngineObject(NULL), + m_slPlayer(NULL), + m_slEngine(NULL), + m_slPlayerPlay(NULL), + m_slPlayerSimpleBufferQueue(NULL), + m_slOutputMixObject(NULL), + m_slSpeakerVolume(NULL), + m_slRecorder(NULL), + m_slRecorderRecord(NULL), + m_slAudioIODeviceCapabilities(NULL), + m_slRecorderSimpleBufferQueue(NULL), + m_slMicVolume(NULL), + _playQueueSeq(0), + _recCurrentSeq(0), + _recBufferTotalSize(0), + _recQueueSeq(0), #endif -m_nMicDeviceId(0), -m_pCallback(pCallback), -m_bInitialized(false), -m_bSpeakerInitialized(false), -m_bSpeakerOn(false), -m_bPlayoutInitialized(false), -m_bRecordingInitialized(false), -m_bMicrophoneInitialized(false), -m_bStereoPlayout(false), -m_bStereoRecording(false), -m_nPlayoutSampleRate(PLAYOUT_SAMPLE_RATE), -m_nRecordingSampleRate(RECORDING_SAMPLE_RATE), -m_nRecordingBufferSize(RECORDING_BUFFER_SIZE), -m_nPlayoutBufferSize(PLAYOUT_BUFFER_SIZE), -m_bPlaying(false), -m_bRecording(false), -m_nSpeakerVolume(0), -m_nMinSpeakerVolume(0), -m_nMaxSpeakerVolume(0) + m_nMicDeviceId(0), + m_pCallback(pCallback), + m_bInitialized(false), + m_bSpeakerInitialized(false), + m_bSpeakerOn(false), + m_bPlayoutInitialized(false), + m_bRecordingInitialized(false), + m_bMicrophoneInitialized(false), + m_bStereoPlayout(false), + m_bStereoRecording(false), + m_nPlayoutSampleRate(PLAYOUT_SAMPLE_RATE), + m_nRecordingSampleRate(RECORDING_SAMPLE_RATE), + m_nRecordingBufferSize(RECORDING_BUFFER_SIZE), + m_nPlayoutBufferSize(PLAYOUT_BUFFER_SIZE), + m_bPlaying(false), + m_bRecording(false), + m_nSpeakerVolume(0), + m_nMinSpeakerVolume(0), + m_nMaxSpeakerVolume(0) { #if AUDIO_OPENSLES_UNDER_ANDROID - memset(_playQueueBuffer, 0, sizeof(_playQueueBuffer)); + memset(_playQueueBuffer, 0, sizeof(_playQueueBuffer)); memset(_recQueueBuffer, 0, sizeof(_recQueueBuffer)); memset(_recBuffer, 0, sizeof(_recBuffer)); memset(_recLength, 0, sizeof(_recLength)); @@ -94,22 +107,22 @@ SLAudioDevice::~SLAudioDevice() } int SLAudioDevice::SetCallback(const SLAudioDeviceCallback* pCallback) -{ - m_pCallback = pCallback; - return 0; +{ + m_pCallback = pCallback; + return 0; } int SLAudioDevice::Init() { - CHECK_FALSE(m_bInitialized, "Already initialized"); + CHECK_FALSE(m_bInitialized, "Already initialized"); - AUDIO_OPENSLES_DEBUG_INFO("SLAudioDevice::Init()"); + AUDIO_OPENSLES_DEBUG_INFO("SLAudioDevice::Init()"); #if AUDIO_OPENSLES_UNDER_ANDROID - SLresult slResult; + SLresult slResult; SLEngineOption EngineOption[] = { - { (SLuint32) SL_ENGINEOPTION_THREADSAFE, (SLuint32) SL_BOOLEAN_TRUE }, + { (SLuint32) SL_ENGINEOPTION_THREADSAFE, (SLuint32) SL_BOOLEAN_TRUE }, }; slResult = slCreateEngine(&m_slEngineObject, 1, EngineOption, 0, NULL, NULL); if (slResult != SL_RESULT_SUCCESS) { @@ -126,152 +139,160 @@ int SLAudioDevice::Init() } #endif /* AUDIO_OPENSLES_UNDER_ANDROID */ - m_bInitialized = true; - AUDIO_OPENSLES_DEBUG_INFO("SL engine initialized"); - return 0; + m_bInitialized = true; + AUDIO_OPENSLES_DEBUG_INFO("SL engine initialized"); + return 0; } bool SLAudioDevice::Initialized() { - return m_bInitialized; + return m_bInitialized; } int SLAudioDevice::SpeakerIsAvailable(bool *pAvailable) { - CHECK_TRUE(m_bInitialized, "Not initialized"); + CHECK_TRUE(m_bInitialized, "Not initialized"); - if(!pAvailable){ - AUDIO_OPENSLES_DEBUG_ERROR("Invalid parameter"); - return -1; - } + if(!pAvailable) { + AUDIO_OPENSLES_DEBUG_ERROR("Invalid parameter"); + return -1; + } - *pAvailable = true; - return 0; + *pAvailable = true; + return 0; } int SLAudioDevice::InitSpeaker() { - AUDIO_OPENSLES_DEBUG_INFO("SLAudioDevice::InitSpeaker()"); + AUDIO_OPENSLES_DEBUG_INFO("SLAudioDevice::InitSpeaker()"); - CHECK_TRUE(m_bInitialized, "Not initialized"); - - if(m_bSpeakerInitialized){ - return 0; - } + CHECK_TRUE(m_bInitialized, "Not initialized"); - m_bSpeakerInitialized = true; - return 0; + if(m_bSpeakerInitialized) { + return 0; + } + + m_bSpeakerInitialized = true; + return 0; } int SLAudioDevice::SetMaxSpeakerVolume(int nMaxSpeakerVolume) { - CHECK_TRUE(m_bSpeakerInitialized, "Speaker not initialized"); - AUDIO_OPENSLES_DEBUG_INFO("SetMaxSpeakerVolume(%d)", nMaxSpeakerVolume); - m_nMaxSpeakerVolume = nMaxSpeakerVolume; - return 0; + CHECK_TRUE(m_bSpeakerInitialized, "Speaker not initialized"); + AUDIO_OPENSLES_DEBUG_INFO("SetMaxSpeakerVolume(%d)", nMaxSpeakerVolume); + m_nMaxSpeakerVolume = nMaxSpeakerVolume; + return 0; } int SLAudioDevice::SetMinSpeakerVolume(int nMinSpeakerVolume) { - CHECK_TRUE(m_bSpeakerInitialized, "Speaker not initialized"); - AUDIO_OPENSLES_DEBUG_INFO("SetMinSpeakerVolume(%d)", nMinSpeakerVolume); - m_nMinSpeakerVolume = nMinSpeakerVolume; - return 0; + CHECK_TRUE(m_bSpeakerInitialized, "Speaker not initialized"); + AUDIO_OPENSLES_DEBUG_INFO("SetMinSpeakerVolume(%d)", nMinSpeakerVolume); + m_nMinSpeakerVolume = nMinSpeakerVolume; + return 0; } int SLAudioDevice::SetSpeakerVolume(int nSpeakerVolume) { - CHECK_TRUE(m_bSpeakerInitialized, "Speaker not initialized"); - AUDIO_OPENSLES_DEBUG_INFO("SetSpeakerVolume(%d)", nSpeakerVolume); - m_nSpeakerVolume = nSpeakerVolume; - return 0; + CHECK_TRUE(m_bSpeakerInitialized, "Speaker not initialized"); + AUDIO_OPENSLES_DEBUG_INFO("SetSpeakerVolume(%d)", nSpeakerVolume); + m_nSpeakerVolume = nSpeakerVolume; + return 0; } int SLAudioDevice::SetSpeakerOn(bool bSpeakerOn) { - CHECK_TRUE(m_bSpeakerInitialized, "Speaker not initialized"); - - AUDIO_OPENSLES_DEBUG_INFO("SetSpeakerOn(%s -> %s)", (m_bSpeakerOn ? "true" : "false"), (bSpeakerOn ? "true" : "false")); - int ret = 0; - bool oldValue = m_bSpeakerOn; - m_bSpeakerOn = bSpeakerOn; // update value beacause use in PlayoutApplyNewConfig(); - if(m_bPlayoutInitialized && (oldValue != bSpeakerOn)){ - ret = PlayoutApplyNewConfig(); - } - - if(ret != 0){ - m_bSpeakerOn = oldValue; - } - - return ret; + CHECK_TRUE(m_bSpeakerInitialized, "Speaker not initialized"); + + AUDIO_OPENSLES_DEBUG_INFO("SetSpeakerOn(%s -> %s)", (m_bSpeakerOn ? "true" : "false"), (bSpeakerOn ? "true" : "false")); + int ret = 0; + bool oldValue = m_bSpeakerOn; + m_bSpeakerOn = bSpeakerOn; // update value beacause use in PlayoutApplyNewConfig(); + if(m_bPlayoutInitialized && (oldValue != bSpeakerOn)) { + ret = PlayoutApplyNewConfig(); + } + + if(ret != 0) { + m_bSpeakerOn = oldValue; + } + + return ret; } int SLAudioDevice::PlayoutIsAvailable(bool *pAvailable) { - CHECK_TRUE(m_bInitialized, "Not initialized"); - CHECK_PLAYOUT_NOT_INITIALIZED(); + CHECK_TRUE(m_bInitialized, "Not initialized"); + CHECK_PLAYOUT_NOT_INITIALIZED(); - if(!pAvailable){ - AUDIO_OPENSLES_DEBUG_ERROR("Invalid parameter"); - return -1; - } + if(!pAvailable) { + AUDIO_OPENSLES_DEBUG_ERROR("Invalid parameter"); + return -1; + } - *pAvailable = true; - return 0; + *pAvailable = true; + return 0; } int SLAudioDevice::SetStereoPlayout(bool bEnabled) { - CHECK_TRUE(m_bInitialized, "Not initialized"); - CHECK_PLAYOUT_NOT_INITIALIZED(); - m_bStereoPlayout = bEnabled; - return 0; + CHECK_TRUE(m_bInitialized, "Not initialized"); + CHECK_PLAYOUT_NOT_INITIALIZED(); + m_bStereoPlayout = bEnabled; + return 0; } int SLAudioDevice::SetPlayoutBuffer(int nPlayoutBufferSize) { - CHECK_TRUE(m_bInitialized, "Not initialized"); - CHECK_PLAYOUT_NOT_INITIALIZED(); + CHECK_TRUE(m_bInitialized, "Not initialized"); + CHECK_PLAYOUT_NOT_INITIALIZED(); - if(PLAYOUT_BUFFER_SIZE != nPlayoutBufferSize){ - AUDIO_OPENSLES_DEBUG_ERROR("Invalid parameter"); - return -1; - } + if(PLAYOUT_BUFFER_SIZE != nPlayoutBufferSize) { + AUDIO_OPENSLES_DEBUG_ERROR("Invalid parameter"); + return -1; + } - m_nPlayoutBufferSize = nPlayoutBufferSize; - return 0; + m_nPlayoutBufferSize = nPlayoutBufferSize; + return 0; } int SLAudioDevice::SetPlayoutSampleRate(int nPlayoutSampleRate) { - CHECK_TRUE(m_bInitialized, "Not initialized"); - CHECK_PLAYOUT_NOT_INITIALIZED(); - - AUDIO_OPENSLES_DEBUG_INFO("SetPlayoutSampleRate(%d)", nPlayoutSampleRate); - - switch(nPlayoutSampleRate){ - case 8000: case 11025: case 16000: case 22050: case 24000: case 32000: case 44100: case 64000: case 88200: case 96000: case 192000: - { - m_nPlayoutSampleRate = nPlayoutSampleRate; - return 0; - } - default: - { - AUDIO_OPENSLES_DEBUG_ERROR("%d not valid sampling rate", nPlayoutSampleRate); - return -1; - } - } + CHECK_TRUE(m_bInitialized, "Not initialized"); + CHECK_PLAYOUT_NOT_INITIALIZED(); + + AUDIO_OPENSLES_DEBUG_INFO("SetPlayoutSampleRate(%d)", nPlayoutSampleRate); + + switch(nPlayoutSampleRate) { + case 8000: + case 11025: + case 16000: + case 22050: + case 24000: + case 32000: + case 44100: + case 64000: + case 88200: + case 96000: + case 192000: { + m_nPlayoutSampleRate = nPlayoutSampleRate; + return 0; + } + default: { + AUDIO_OPENSLES_DEBUG_ERROR("%d not valid sampling rate", nPlayoutSampleRate); + return -1; + } + } } int SLAudioDevice::InitPlayout() { - CHECK_TRUE(m_bInitialized, "Not initialized"); - - AUDIO_OPENSLES_DEBUG_INFO("SLAudioDevice::InitPlayout()"); + CHECK_TRUE(m_bInitialized, "Not initialized"); - if(m_bPlayoutInitialized){ - return 0; - } + AUDIO_OPENSLES_DEBUG_INFO("SLAudioDevice::InitPlayout()"); + + if(m_bPlayoutInitialized) { + return 0; + } if (m_bPlaying) { AUDIO_OPENSLES_DEBUG_ERROR("Playout already started"); @@ -285,7 +306,7 @@ int SLAudioDevice::InitPlayout() #if AUDIO_OPENSLES_UNDER_ANDROID - if (m_slEngineObject == NULL || m_slEngine == NULL) { + if (m_slEngineObject == NULL || m_slEngine == NULL) { AUDIO_OPENSLES_DEBUG_ERROR("SLObject or Engiine is NULL"); return -1; } @@ -305,68 +326,68 @@ int SLAudioDevice::InitPlayout() req[i] = SL_BOOLEAN_FALSE; } ids[0] = SL_IID_ENVIRONMENTALREVERB; - + if ((slResult = (*m_slEngine)->CreateOutputMix(m_slEngine, &m_slOutputMixObject, 1, ids, req)) != SL_RESULT_SUCCESS) { AUDIO_OPENSLES_DEBUG_ERROR("CreateOutputMix() for playout failed with error code = %d", slResult); return -1; } - + if ((slResult = (*m_slOutputMixObject)->Realize(m_slOutputMixObject, SL_BOOLEAN_FALSE)) != SL_RESULT_SUCCESS) { AUDIO_OPENSLES_DEBUG_ERROR("Failed to realize SL Output Mix object for playout with error code = %d", slResult); return -1; } - + simpleBufferQueue.locatorType = SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE; simpleBufferQueue.numBuffers = N_PLAY_QUEUE_BUFFERS; - + pcm.formatType = SL_DATAFORMAT_PCM; - pcm.numChannels = m_bStereoPlayout ? 2 : 1; - pcm.samplesPerSec = SL_SAMPLING_RATE(m_nPlayoutSampleRate); + pcm.numChannels = m_bStereoPlayout ? 2 : 1; + pcm.samplesPerSec = SL_SAMPLING_RATE(m_nPlayoutSampleRate); pcm.bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_16; pcm.containerSize = SL_PCMSAMPLEFORMAT_FIXED_16; - pcm.channelMask = m_bStereoRecording ? (SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT) : SL_SPEAKER_FRONT_CENTER; + pcm.channelMask = m_bStereoRecording ? (SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT) : SL_SPEAKER_FRONT_CENTER; pcm.endianness = SL_BYTEORDER_LITTLEENDIAN; - - audioSource.pFormat = (void *) &pcm; + + audioSource.pFormat = (void *) &pcm; audioSource.pLocator = (void *) &simpleBufferQueue; locator_outputmix.locatorType = SL_DATALOCATOR_OUTPUTMIX; locator_outputmix.outputMix = m_slOutputMixObject; audioSink.pLocator = (void *) &locator_outputmix; audioSink.pFormat = NULL; - + ids[0] = SL_IID_ANDROIDSIMPLEBUFFERQUEUE; ids[1] = SL_IID_EFFECTSEND; - ids[2] = SL_IID_ANDROIDCONFIGURATION; - ids[3] = SL_IID_VOLUME; + ids[2] = SL_IID_ANDROIDCONFIGURATION; + ids[3] = SL_IID_VOLUME; req[0] = SL_BOOLEAN_TRUE; req[1] = SL_BOOLEAN_TRUE; - req[2] = SL_BOOLEAN_TRUE; - req[3] = SL_BOOLEAN_TRUE; + req[2] = SL_BOOLEAN_TRUE; + req[3] = SL_BOOLEAN_TRUE; // Create the player if ((slResult = (*m_slEngine)->CreateAudioPlayer(m_slEngine, &m_slPlayer, &audioSource, &audioSink, 3, ids, req)) != SL_RESULT_SUCCESS) { AUDIO_OPENSLES_DEBUG_ERROR("Failed to create Audio Player with error code = %d", slResult); return -1; } - - // set stream type - if(!m_bSpeakerOn){ // only set if speaker OFF, otherwise default is ON. "SL_ANDROID_STREAM_MEDIA" doen't look to work on all devices - static SLAndroidConfigurationItf _playerStreamConfig; - if((slResult = (*m_slPlayer)->GetInterface(m_slPlayer, SL_IID_ANDROIDCONFIGURATION, &_playerStreamConfig)) != SL_RESULT_SUCCESS){ - AUDIO_OPENSLES_DEBUG_ERROR("Failed to get player configuration with error code = %d", slResult); - return -1; - } - else{ - static SLint32 _playerStreamType = m_bSpeakerOn ? SL_ANDROID_STREAM_MEDIA : SL_ANDROID_STREAM_VOICE; - static SLint32 _playerStreamTypeSize = sizeof(SLint32); - AUDIO_OPENSLES_DEBUG_INFO("_playerStreamType=%d", _playerStreamType); - if((slResult = (*_playerStreamConfig)->SetConfiguration(_playerStreamConfig, SL_ANDROID_KEY_STREAM_TYPE, &_playerStreamType, _playerStreamTypeSize))){ - AUDIO_OPENSLES_DEBUG_ERROR("Failed to set player stream type with error code = %d", slResult); - return -2; - } - } - } + + // set stream type + if(!m_bSpeakerOn) { // only set if speaker OFF, otherwise default is ON. "SL_ANDROID_STREAM_MEDIA" doen't look to work on all devices + static SLAndroidConfigurationItf _playerStreamConfig; + if((slResult = (*m_slPlayer)->GetInterface(m_slPlayer, SL_IID_ANDROIDCONFIGURATION, &_playerStreamConfig)) != SL_RESULT_SUCCESS) { + AUDIO_OPENSLES_DEBUG_ERROR("Failed to get player configuration with error code = %d", slResult); + return -1; + } + else { + static SLint32 _playerStreamType = m_bSpeakerOn ? SL_ANDROID_STREAM_MEDIA : SL_ANDROID_STREAM_VOICE; + static SLint32 _playerStreamTypeSize = sizeof(SLint32); + AUDIO_OPENSLES_DEBUG_INFO("_playerStreamType=%d", _playerStreamType); + if((slResult = (*_playerStreamConfig)->SetConfiguration(_playerStreamConfig, SL_ANDROID_KEY_STREAM_TYPE, &_playerStreamType, _playerStreamTypeSize))) { + AUDIO_OPENSLES_DEBUG_ERROR("Failed to set player stream type with error code = %d", slResult); + return -2; + } + } + } // Realizing the player in synchronous mode if ((slResult = (*m_slPlayer)->Realize(m_slPlayer, SL_BOOLEAN_FALSE)) != SL_RESULT_SUCCESS) { @@ -384,53 +405,53 @@ int SLAudioDevice::InitPlayout() } // Setup to receive buffer queue event callbacks - if ((slResult = (*m_slPlayerSimpleBufferQueue)->RegisterCallback(m_slPlayerSimpleBufferQueue, PlayerSimpleBufferQueueCallback, this)) != SL_RESULT_SUCCESS) { + if ((slResult = (*m_slPlayerSimpleBufferQueue)->RegisterCallback(m_slPlayerSimpleBufferQueue, PlayerSimpleBufferQueueCallback, this)) != SL_RESULT_SUCCESS) { AUDIO_OPENSLES_DEBUG_ERROR("Failed to register Player Callback"); return -1; } #endif /* AUDIO_OPENSLES_UNDER_ANDROID */ - m_bPlayoutInitialized = true; + m_bPlayoutInitialized = true; - AUDIO_OPENSLES_DEBUG_INFO("Playout initialized"); + AUDIO_OPENSLES_DEBUG_INFO("Playout initialized"); - return 0; + return 0; } int SLAudioDevice::StereoPlayout(bool *pEnabled) { - CHECK_TRUE(m_bInitialized, "Not initialized"); - CHECK_PLAYOUT_INITIALIZED(); + CHECK_TRUE(m_bInitialized, "Not initialized"); + CHECK_PLAYOUT_INITIALIZED(); - if(!pEnabled){ - AUDIO_OPENSLES_DEBUG_ERROR("Invalid parameter"); - return -1; - } + if(!pEnabled) { + AUDIO_OPENSLES_DEBUG_ERROR("Invalid parameter"); + return -1; + } - *pEnabled = m_bStereoPlayout; - return 0; + *pEnabled = m_bStereoPlayout; + return 0; } int SLAudioDevice::PlayoutSampleRate(int *pPlayoutSampleRate) { - CHECK_TRUE(m_bInitialized, "Not initialized"); - CHECK_PLAYOUT_INITIALIZED(); + CHECK_TRUE(m_bInitialized, "Not initialized"); + CHECK_PLAYOUT_INITIALIZED(); - if(!pPlayoutSampleRate){ - AUDIO_OPENSLES_DEBUG_ERROR("Invalid parameter"); - return -1; - } + if(!pPlayoutSampleRate) { + AUDIO_OPENSLES_DEBUG_ERROR("Invalid parameter"); + return -1; + } - *pPlayoutSampleRate = m_nPlayoutSampleRate; - return 0; + *pPlayoutSampleRate = m_nPlayoutSampleRate; + return 0; } int SLAudioDevice::StartPlayout() { - AUDIO_OPENSLES_DEBUG_INFO("SLAudioDevice::StartPlayout()"); + AUDIO_OPENSLES_DEBUG_INFO("SLAudioDevice::StartPlayout()"); - CHECK_TRUE(m_bInitialized, "Not initialized"); - CHECK_PLAYOUT_INITIALIZED(); + CHECK_TRUE(m_bInitialized, "Not initialized"); + CHECK_PLAYOUT_INITIALIZED(); if (m_bPlaying) { return 0; @@ -450,21 +471,21 @@ int SLAudioDevice::StartPlayout() SLresult slResult; /* Enqueue a set of zero buffers to get the ball rolling */ - uint32_t nSample10ms = m_nPlayoutSampleRate / 100; + uint32_t nSample10ms = m_nPlayoutSampleRate / 100; uint8_t playBuffer[nSample10ms << BYTES_PER_SAMPLE_LOG2]; uint32_t noSamplesOut(0); { - // get data from jitter buffer - noSamplesOut = SLAudioDevice::PullPlayoutData(playBuffer, nSample10ms); - if(noSamplesOut != nSample10ms){ - AUDIO_OPENSLES_DEBUG_WARN("%d not expected as samples output count value", noSamplesOut); - noSamplesOut = nSample10ms; - memset(_playQueueBuffer[_playQueueSeq], 0, (noSamplesOut << BYTES_PER_SAMPLE_LOG2)); - } - else{ - memcpy(_playQueueBuffer[_playQueueSeq], playBuffer, (noSamplesOut << BYTES_PER_SAMPLE_LOG2)); - } - + // get data from jitter buffer + noSamplesOut = SLAudioDevice::PullPlayoutData(playBuffer, nSample10ms); + if(noSamplesOut != nSample10ms) { + AUDIO_OPENSLES_DEBUG_WARN("%d not expected as samples output count value", noSamplesOut); + noSamplesOut = nSample10ms; + memset(_playQueueBuffer[_playQueueSeq], 0, (noSamplesOut << BYTES_PER_SAMPLE_LOG2)); + } + else { + memcpy(_playQueueBuffer[_playQueueSeq], playBuffer, (noSamplesOut << BYTES_PER_SAMPLE_LOG2)); + } + // write the buffer data we into the device if ((slResult = (*m_slPlayerSimpleBufferQueue)->Enqueue(m_slPlayerSimpleBufferQueue, (void*) _playQueueBuffer[_playQueueSeq], (noSamplesOut << 1))) != SL_RESULT_SUCCESS) { AUDIO_OPENSLES_DEBUG_ERROR("Player simpler buffer queue Enqueue failed with error code = %d and noSamplesOut = %d", slResult, noSamplesOut); @@ -473,42 +494,42 @@ int SLAudioDevice::StartPlayout() } // Play the PCM samples using a buffer queue - m_bPlaying = true; + m_bPlaying = true; if ((slResult = (*m_slPlayerPlay)->SetPlayState(m_slPlayerPlay, SL_PLAYSTATE_PLAYING)) != SL_RESULT_SUCCESS) { AUDIO_OPENSLES_DEBUG_ERROR("Failed to start playout with error code = %d", slResult); - m_bPlaying = false; + m_bPlaying = false; return -1; } #else - m_bPlaying = true; + m_bPlaying = true; #endif /* AUDIO_OPENSLES_UNDER_ANDROID */ - AUDIO_OPENSLES_DEBUG_INFO("Payout started - rate=%d", m_nPlayoutSampleRate); + AUDIO_OPENSLES_DEBUG_INFO("Payout started - rate=%d", m_nPlayoutSampleRate); - return 0; + return 0; } bool SLAudioDevice::Playing() { - return m_bPlaying; + return m_bPlaying; } int SLAudioDevice::StopPlayout() { - AUDIO_OPENSLES_DEBUG_INFO("SLAudioDevice::StopPlayout()"); + AUDIO_OPENSLES_DEBUG_INFO("SLAudioDevice::StopPlayout()"); - if(!m_bPlaying){ - return 0; - } + if(!m_bPlaying) { + return 0; + } #if AUDIO_OPENSLES_UNDER_ANDROID if ((m_slPlayerPlay != NULL) && (m_slOutputMixObject != NULL) && (m_slPlayer != NULL)) { - SLresult slResult; - + SLresult slResult; + if ((slResult = (*m_slPlayerPlay)->SetPlayState(m_slPlayerPlay, SL_PLAYSTATE_STOPPED)) != SL_RESULT_SUCCESS) { AUDIO_OPENSLES_DEBUG_ERROR("Failed to stop playout with error code = %d", slResult); return -1; } - + if ((slResult = (*m_slPlayerSimpleBufferQueue)->Clear(m_slPlayerSimpleBufferQueue)) != SL_RESULT_SUCCESS) { AUDIO_OPENSLES_DEBUG_ERROR("Failed to clear recorder buffer queue"); return -1; @@ -516,7 +537,7 @@ int SLAudioDevice::StopPlayout() // Destroy the player (*m_slPlayer)->Destroy(m_slPlayer); - // Destroy Output Mix object + // Destroy Output Mix object (*m_slOutputMixObject)->Destroy(m_slOutputMixObject); m_slPlayer = NULL; m_slPlayerPlay = NULL; @@ -525,124 +546,132 @@ int SLAudioDevice::StopPlayout() } #endif - AUDIO_OPENSLES_DEBUG_INFO("Playout stopped"); - m_bPlayoutInitialized = false; - m_bPlaying = false; - return 0; + AUDIO_OPENSLES_DEBUG_INFO("Playout stopped"); + m_bPlayoutInitialized = false; + m_bPlaying = false; + return 0; } int SLAudioDevice::RecordingIsAvailable(bool *pAvailable) { - CHECK_TRUE(m_bInitialized, "Device not initialized"); - CHECK_RECORDING_NOT_INITIALIZED(); + CHECK_TRUE(m_bInitialized, "Device not initialized"); + CHECK_RECORDING_NOT_INITIALIZED(); - if(!pAvailable){ - AUDIO_OPENSLES_DEBUG_ERROR("Invalid parameter"); - return -1; - } + if(!pAvailable) { + AUDIO_OPENSLES_DEBUG_ERROR("Invalid parameter"); + return -1; + } - *pAvailable = true; - return 0; + *pAvailable = true; + return 0; } int SLAudioDevice::MicrophoneIsAvailable(bool *pAvailable) { - CHECK_TRUE(m_bInitialized, "Device not initialized"); - CHECK_RECORDING_NOT_INITIALIZED(); + CHECK_TRUE(m_bInitialized, "Device not initialized"); + CHECK_RECORDING_NOT_INITIALIZED(); - if(!pAvailable){ - AUDIO_OPENSLES_DEBUG_ERROR("Invalid parameter"); - return -1; - } + if(!pAvailable) { + AUDIO_OPENSLES_DEBUG_ERROR("Invalid parameter"); + return -1; + } - *pAvailable = true; - return 0; + *pAvailable = true; + return 0; } int SLAudioDevice::InitMicrophone() { - AUDIO_OPENSLES_DEBUG_INFO("SLAudioDevice::InitMicrophone()"); - CHECK_TRUE(m_bInitialized, "Device not initialized"); + AUDIO_OPENSLES_DEBUG_INFO("SLAudioDevice::InitMicrophone()"); + CHECK_TRUE(m_bInitialized, "Device not initialized"); - if(m_bMicrophoneInitialized){ - return 0; - } + if(m_bMicrophoneInitialized) { + return 0; + } - m_bMicrophoneInitialized = true; - return 0; + m_bMicrophoneInitialized = true; + return 0; } int SLAudioDevice::SetMicrophoneVolume(int nMicrophoneVolume) { - CHECK_MICROPHONE_INITIALIZED(); + CHECK_MICROPHONE_INITIALIZED(); - AUDIO_OPENSLES_DEBUG_INFO("SetMicrophoneVolume(%d)", nMicrophoneVolume); + AUDIO_OPENSLES_DEBUG_INFO("SetMicrophoneVolume(%d)", nMicrophoneVolume); #if AUDIO_OPENSLES_UNDER_ANDROID if (m_slMicVolume == NULL) { - SLresult slResult; + SLresult slResult; if ((slResult = (*m_slEngineObject)->GetInterface(m_slEngineObject, SL_IID_DEVICEVOLUME, (void*) &m_slMicVolume)) != SL_RESULT_SUCCESS) { AUDIO_OPENSLES_DEBUG_ERROR("Failed to get 'SL_IID_DEVICEVOLUME' interface with error code = %d", slResult); - return -1; + return -1; } } if (m_slMicVolume != NULL) { - SLresult slResult; + SLresult slResult; int vol(0); vol = ((nMicrophoneVolume * (m_nMaxSpeakerVolume - m_nMinSpeakerVolume) + (int) (255 / 2)) / (255)) + m_nMinSpeakerVolume; if ((slResult = (*m_slMicVolume)->SetVolume(m_slMicVolume, m_nMicDeviceId, vol)) != SL_RESULT_SUCCESS) { AUDIO_OPENSLES_DEBUG_ERROR("SetVolume() failed with error code = %d", slResult); - return -1; + return -1; } } #endif /* AUDIO_OPENSLES_UNDER_ANDROID */ - return 0; + return 0; } int SLAudioDevice::SetStereoRecording(bool bEnabled) { - CHECK_TRUE(m_bInitialized, "Not initialized"); - CHECK_RECORDING_NOT_INITIALIZED(); - AUDIO_OPENSLES_DEBUG_INFO("SetStereoRecording(%s)", bEnabled ? "True" : "False"); - m_bStereoRecording = bEnabled; - return 0; + CHECK_TRUE(m_bInitialized, "Not initialized"); + CHECK_RECORDING_NOT_INITIALIZED(); + AUDIO_OPENSLES_DEBUG_INFO("SetStereoRecording(%s)", bEnabled ? "True" : "False"); + m_bStereoRecording = bEnabled; + return 0; } int SLAudioDevice::SetRecordingSampleRate(int nRecordingSampleRate) { - CHECK_TRUE(m_bInitialized, "Not initialized"); - CHECK_RECORDING_NOT_INITIALIZED(); - - AUDIO_OPENSLES_DEBUG_INFO("SetRecordingSampleRate(%d)", nRecordingSampleRate); - - switch(nRecordingSampleRate){ - case 8000: case 11025: case 16000: case 22050: case 24000: case 32000: case 44100: case 64000: case 88200: case 96000: case 192000: - { - m_nRecordingSampleRate = nRecordingSampleRate; - return 0; - } - default: - { - AUDIO_OPENSLES_DEBUG_ERROR("%d not valid sampling rate", nRecordingSampleRate); - return -1; - } - } + CHECK_TRUE(m_bInitialized, "Not initialized"); + CHECK_RECORDING_NOT_INITIALIZED(); + + AUDIO_OPENSLES_DEBUG_INFO("SetRecordingSampleRate(%d)", nRecordingSampleRate); + + switch(nRecordingSampleRate) { + case 8000: + case 11025: + case 16000: + case 22050: + case 24000: + case 32000: + case 44100: + case 64000: + case 88200: + case 96000: + case 192000: { + m_nRecordingSampleRate = nRecordingSampleRate; + return 0; + } + default: { + AUDIO_OPENSLES_DEBUG_ERROR("%d not valid sampling rate", nRecordingSampleRate); + return -1; + } + } } int SLAudioDevice::InitRecording() { - CHECK_TRUE(m_bInitialized, "Not initialized"); + CHECK_TRUE(m_bInitialized, "Not initialized"); - AUDIO_OPENSLES_DEBUG_INFO("SLAudioDevice::InitRecording()"); + AUDIO_OPENSLES_DEBUG_INFO("SLAudioDevice::InitRecording()"); if (m_bRecording) { AUDIO_OPENSLES_DEBUG_ERROR("Recording already started"); return -1; } - if (m_bRecordingInitialized) { + if (m_bRecordingInitialized) { return 0; } @@ -696,21 +725,21 @@ int SLAudioDevice::InitRecording() return -1; } - // Set stream type - SLAndroidConfigurationItf slRecorderConfig; - SLint32 slStreamType = SL_ANDROID_RECORDING_PRESET_GENERIC; + // Set stream type + SLAndroidConfigurationItf slRecorderConfig; + SLint32 slStreamType = SL_ANDROID_RECORDING_PRESET_GENERIC; slResult = (*m_slRecorder)->GetInterface(m_slRecorder, SL_IID_ANDROIDCONFIGURATION, &slRecorderConfig); if(slResult != SL_RESULT_SUCCESS) { AUDIO_OPENSLES_DEBUG_ERROR("GetInterface(SL_IID_ANDROIDCONFIGURATION) failed with error code = %d", slResult); return -1; } - AUDIO_OPENSLES_DEBUG_INFO("Recording stream type = %d", slStreamType); + AUDIO_OPENSLES_DEBUG_INFO("Recording stream type = %d", slStreamType); slResult = (*slRecorderConfig)->SetConfiguration(slRecorderConfig, SL_ANDROID_KEY_RECORDING_PRESET, &slStreamType, sizeof(SLint32)); - if(slResult != SL_RESULT_SUCCESS) { + if(slResult != SL_RESULT_SUCCESS) { AUDIO_OPENSLES_DEBUG_ERROR("SetConfiguration(SL_ANDROID_KEY_RECORDING_PRESET) failed with error code = %d", slResult); return -1; } - + // Realizing the recorder in synchronous mode. slResult = (*m_slRecorder)->Realize(m_slRecorder, SL_BOOLEAN_FALSE); @@ -742,47 +771,47 @@ int SLAudioDevice::InitRecording() #endif /* AUDIO_OPENSLES_UNDER_ANDROID */ - AUDIO_OPENSLES_DEBUG_INFO("Recording initialized"); + AUDIO_OPENSLES_DEBUG_INFO("Recording initialized"); - m_bRecordingInitialized = true; + m_bRecordingInitialized = true; - return 0; + return 0; } int SLAudioDevice::StereoRecording(bool *pEnabled) { - CHECK_TRUE(m_bInitialized, "Not initialized"); - CHECK_RECORDING_INITIALIZED(); + CHECK_TRUE(m_bInitialized, "Not initialized"); + CHECK_RECORDING_INITIALIZED(); - if(!pEnabled){ - AUDIO_OPENSLES_DEBUG_ERROR("Invalid parameter"); - return -1; - } + if(!pEnabled) { + AUDIO_OPENSLES_DEBUG_ERROR("Invalid parameter"); + return -1; + } - *pEnabled = m_bStereoRecording; - return 0; + *pEnabled = m_bStereoRecording; + return 0; } int SLAudioDevice::RecordingSampleRate(int *pRecordingSampleRate) { - CHECK_TRUE(m_bInitialized, "Not initialized"); - CHECK_RECORDING_INITIALIZED(); + CHECK_TRUE(m_bInitialized, "Not initialized"); + CHECK_RECORDING_INITIALIZED(); - if(!pRecordingSampleRate){ - AUDIO_OPENSLES_DEBUG_ERROR("Invalid parameter"); - return -1; - } + if(!pRecordingSampleRate) { + AUDIO_OPENSLES_DEBUG_ERROR("Invalid parameter"); + return -1; + } - *pRecordingSampleRate = m_nRecordingSampleRate; - return 0; + *pRecordingSampleRate = m_nRecordingSampleRate; + return 0; } int SLAudioDevice::StartRecording() { - AUDIO_OPENSLES_DEBUG_INFO("SLAudioDevice::StartRecording()"); + AUDIO_OPENSLES_DEBUG_INFO("SLAudioDevice::StartRecording()"); - CHECK_TRUE(m_bInitialized, "Not initialized"); - CHECK_RECORDING_INITIALIZED(); + CHECK_TRUE(m_bInitialized, "Not initialized"); + CHECK_RECORDING_INITIALIZED(); if (m_bRecording) { return 0; @@ -791,13 +820,13 @@ int SLAudioDevice::StartRecording() #if AUDIO_OPENSLES_UNDER_ANDROID if (m_slRecorderRecord == NULL) { - AUDIO_OPENSLES_DEBUG_ERROR("RecordITF is NULL"); + AUDIO_OPENSLES_DEBUG_ERROR("RecordITF is NULL"); return -1; } if (m_slRecorderSimpleBufferQueue == NULL) { - AUDIO_OPENSLES_DEBUG_ERROR("Recorder Simple Buffer Queue is NULL"); - return -1; + AUDIO_OPENSLES_DEBUG_ERROR("Recorder Simple Buffer Queue is NULL"); + return -1; } // Reset recording buffer @@ -822,31 +851,31 @@ int SLAudioDevice::StartRecording() _recQueueSeq++; } // Record the audio - m_bRecording = true; + m_bRecording = true; slResult = (*m_slRecorderRecord)->SetRecordState(m_slRecorderRecord, SL_RECORDSTATE_RECORDING); if (slResult != SL_RESULT_SUCCESS) { AUDIO_OPENSLES_DEBUG_ERROR("Failed to start recording with error code = %d", slResult); - m_bRecording = false; + m_bRecording = false; return -1; } #else - m_bRecording = true; + m_bRecording = true; #endif /* AUDIO_OPENSLES_UNDER_ANDROID */ - AUDIO_OPENSLES_DEBUG_INFO("Recording started - rate = %d", m_nRecordingSampleRate); - - return 0; + AUDIO_OPENSLES_DEBUG_INFO("Recording started - rate = %d", m_nRecordingSampleRate); + + return 0; } bool SLAudioDevice::Recording() { - return m_bRecording; + return m_bRecording; } int SLAudioDevice::StopRecording() { - AUDIO_OPENSLES_DEBUG_INFO("SLAudioDevice::StopRecording()"); - if (!m_bRecording) { + AUDIO_OPENSLES_DEBUG_INFO("SLAudioDevice::StopRecording()"); + if (!m_bRecording) { return 0; } #if AUDIO_OPENSLES_UNDER_ANDROID @@ -870,47 +899,47 @@ int SLAudioDevice::StopRecording() } #endif - AUDIO_OPENSLES_DEBUG_INFO("Recording stopped"); - m_bRecording = false; - m_bRecordingInitialized = false; - return 0; + AUDIO_OPENSLES_DEBUG_INFO("Recording stopped"); + m_bRecording = false; + m_bRecordingInitialized = false; + return 0; } int SLAudioDevice::Terminate() { - if (!m_bInitialized) { + if (!m_bInitialized) { return 0; } - if(Recording()){ - StopRecording(); - } + if(Recording()) { + StopRecording(); + } - if(Playing()){ - StopPlayout(); - } + if(Playing()) { + StopPlayout(); + } #if AUDIO_OPENSLES_UNDER_ANDROID - if(m_slPlayer){ - (*m_slPlayer)->Destroy(m_slPlayer); - m_slPlayer = NULL; - m_slPlayerPlay = NULL; - m_slPlayerSimpleBufferQueue = NULL; - } - - if(m_slRecorder){ - (*m_slRecorder)->Destroy(m_slRecorder); - m_slRecorder = NULL; - m_slRecorderRecord = NULL; - m_slRecorderSimpleBufferQueue = NULL; - m_slAudioIODeviceCapabilities = NULL; - } - - if(m_slOutputMixObject){ - (*m_slOutputMixObject)->Destroy(m_slOutputMixObject); - m_slOutputMixObject = NULL; - } + if(m_slPlayer) { + (*m_slPlayer)->Destroy(m_slPlayer); + m_slPlayer = NULL; + m_slPlayerPlay = NULL; + m_slPlayerSimpleBufferQueue = NULL; + } + + if(m_slRecorder) { + (*m_slRecorder)->Destroy(m_slRecorder); + m_slRecorder = NULL; + m_slRecorderRecord = NULL; + m_slRecorderSimpleBufferQueue = NULL; + m_slAudioIODeviceCapabilities = NULL; + } + + if(m_slOutputMixObject) { + (*m_slOutputMixObject)->Destroy(m_slOutputMixObject); + m_slOutputMixObject = NULL; + } if (m_slEngineObject) { (*m_slEngineObject)->Destroy(m_slEngineObject); @@ -919,9 +948,9 @@ int SLAudioDevice::Terminate() } #endif - m_bSpeakerInitialized = false; - m_bPlayoutInitialized = false; - m_bRecordingInitialized = false; + m_bSpeakerInitialized = false; + m_bPlayoutInitialized = false; + m_bRecordingInitialized = false; m_bInitialized = false; return 0; @@ -929,73 +958,73 @@ int SLAudioDevice::Terminate() int SLAudioDevice::PlayoutApplyNewConfig() { - AUDIO_OPENSLES_DEBUG_INFO("SLAudioDevice::PlayoutApplyNewConfig()"); + AUDIO_OPENSLES_DEBUG_INFO("SLAudioDevice::PlayoutApplyNewConfig()"); #if AUDIO_OPENSLES_UNDER_ANDROID - if(m_slPlayer){ - SLresult slResult; - int ret; - bool wasPlaying = Playing(); - - if(wasPlaying){ - if ((ret = StopPlayout())){ - AUDIO_OPENSLES_DEBUG_ERROR("Failed to stop playout for reconf"); - return ret; - } - if((ret = InitPlayout())){ - AUDIO_OPENSLES_DEBUG_ERROR("Failed to init() playout after reconf"); - return ret; - } - } - - if(wasPlaying){ - if((ret = StartPlayout())){ - AUDIO_OPENSLES_DEBUG_ERROR("Failed to start() playout after reconf"); - return ret; - } - } - } + if(m_slPlayer) { + SLresult slResult; + int ret; + bool wasPlaying = Playing(); + + if(wasPlaying) { + if ((ret = StopPlayout())) { + AUDIO_OPENSLES_DEBUG_ERROR("Failed to stop playout for reconf"); + return ret; + } + if((ret = InitPlayout())) { + AUDIO_OPENSLES_DEBUG_ERROR("Failed to init() playout after reconf"); + return ret; + } + } + + if(wasPlaying) { + if((ret = StartPlayout())) { + AUDIO_OPENSLES_DEBUG_ERROR("Failed to start() playout after reconf"); + return ret; + } + } + } #endif /* AUDIO_OPENSLES_UNDER_ANDROID */ - return 0; + return 0; } uint32_t SLAudioDevice::PullPlayoutData(void* pAudioSamples, const uint32_t nSamples) { - if(!pAudioSamples || !nSamples){ - AUDIO_OPENSLES_DEBUG_ERROR("PullPlayoutData() - Invalid parameter"); - return 0; - } - - if(!m_pCallback){ - memset(pAudioSamples, 0, (nSamples << BYTES_PER_SAMPLE_LOG2)); - return nSamples; - } - - uint32_t nSamplesOut = 0; - const_cast<SLAudioDeviceCallback*>(m_pCallback)->NeedMorePlayData(nSamples, - BYTES_PER_SAMPLE, - m_bStereoPlayout ? 2 : 1, - m_nPlayoutSampleRate, - pAudioSamples, - nSamplesOut); - return nSamplesOut; + if(!pAudioSamples || !nSamples) { + AUDIO_OPENSLES_DEBUG_ERROR("PullPlayoutData() - Invalid parameter"); + return 0; + } + + if(!m_pCallback) { + memset(pAudioSamples, 0, (nSamples << BYTES_PER_SAMPLE_LOG2)); + return nSamples; + } + + uint32_t nSamplesOut = 0; + const_cast<SLAudioDeviceCallback*>(m_pCallback)->NeedMorePlayData(nSamples, + BYTES_PER_SAMPLE, + m_bStereoPlayout ? 2 : 1, + m_nPlayoutSampleRate, + pAudioSamples, + nSamplesOut); + return nSamplesOut; } void SLAudioDevice::PushRecordingData(void* pAudioSamples, const uint32_t nSamples) { - if(!pAudioSamples || !nSamples){ - AUDIO_OPENSLES_DEBUG_ERROR("PushRecordingData() - Invalid parameter"); - return; - } - - if(m_pCallback){ - const_cast<SLAudioDeviceCallback*>(m_pCallback)->RecordedDataIsAvailable(pAudioSamples, - nSamples, - BYTES_PER_SAMPLE, - m_bStereoRecording ? 2 : 1, - m_nRecordingSampleRate); - } + if(!pAudioSamples || !nSamples) { + AUDIO_OPENSLES_DEBUG_ERROR("PushRecordingData() - Invalid parameter"); + return; + } + + if(m_pCallback) { + const_cast<SLAudioDeviceCallback*>(m_pCallback)->RecordedDataIsAvailable(pAudioSamples, + nSamples, + BYTES_PER_SAMPLE, + m_bStereoRecording ? 2 : 1, + m_nRecordingSampleRate); + } } #if AUDIO_OPENSLES_UNDER_ANDROID @@ -1004,24 +1033,24 @@ void SLAudioDevice::PlayerSimpleBufferQueueCallback(SLAndroidSimpleBufferQueueIt { SLAudioDevice* This = static_cast<SLAudioDevice*> (pContext); - // AUDIO_OPENSLES_DEBUG_INFO("PlayerSimpleBufferQueueCallback(playing=%s, _playQueueSeq=%d)", (This->m_bPlaying ? "true" : "false"), This->_playQueueSeq); + // AUDIO_OPENSLES_DEBUG_INFO("PlayerSimpleBufferQueueCallback(playing=%s, _playQueueSeq=%d)", (This->m_bPlaying ? "true" : "false"), This->_playQueueSeq); - if (This->m_bPlaying && (This->_playQueueSeq < N_PLAY_QUEUE_BUFFERS)) { - unsigned int noSamp10ms = This->m_nPlayoutSampleRate / 100; + if (This->m_bPlaying && (This->_playQueueSeq < N_PLAY_QUEUE_BUFFERS)) { + unsigned int noSamp10ms = This->m_nPlayoutSampleRate / 100; uint8_t playBuffer[noSamp10ms << BYTES_PER_SAMPLE_LOG2]; uint32_t noSamplesOut = This->PullPlayoutData(playBuffer, noSamp10ms); - + if (noSamp10ms != noSamplesOut) { - if(noSamplesOut){ // (noSamplesOut==0) -> jitter buffer cannot provide data - AUDIO_OPENSLES_DEBUG_ERROR("noSamp10ms (%u) != noSamplesOut (%d)", noSamp10ms, noSamplesOut); - } - noSamplesOut = noSamp10ms; - memset(This->_playQueueBuffer[This->_playQueueSeq], 0, (noSamplesOut << BYTES_PER_SAMPLE_LOG2)); + if(noSamplesOut) { // (noSamplesOut==0) -> jitter buffer cannot provide data + AUDIO_OPENSLES_DEBUG_ERROR("noSamp10ms (%u) != noSamplesOut (%d)", noSamp10ms, noSamplesOut); + } + noSamplesOut = noSamp10ms; + memset(This->_playQueueBuffer[This->_playQueueSeq], 0, (noSamplesOut << BYTES_PER_SAMPLE_LOG2)); } - else{ - memcpy(This->_playQueueBuffer[This->_playQueueSeq], playBuffer, (noSamplesOut << BYTES_PER_SAMPLE_LOG2)); - } - + else { + memcpy(This->_playQueueBuffer[This->_playQueueSeq], playBuffer, (noSamplesOut << BYTES_PER_SAMPLE_LOG2)); + } + SLresult slResult = (*This->m_slPlayerSimpleBufferQueue)->Enqueue(This->m_slPlayerSimpleBufferQueue, This->_playQueueBuffer[This->_playQueueSeq], (noSamplesOut << BYTES_PER_SAMPLE_LOG2)); if (slResult != SL_RESULT_SUCCESS) { AUDIO_OPENSLES_DEBUG_ERROR("Player simpler buffer queue Enqueue failed, noSamplesOut=%d, ret=%d", noSamplesOut, slResult); @@ -1036,31 +1065,30 @@ void SLAudioDevice::RecorderSimpleBufferQueueCallback(SLAndroidSimpleBufferQueue { // AUDIO_OPENSLES_DEBUG_INFO("RecorderSimpleBufferQueueCallback()"); - SLAudioDevice* This = static_cast<SLAudioDevice*> (pContext); + SLAudioDevice* This = static_cast<SLAudioDevice*> (pContext); - if (This->m_bRecording) { + if (This->m_bRecording) { const unsigned int noSamp10ms = This->m_nRecordingSampleRate / 100; - + #if 1 // not using async thread - // push data - This->PushRecordingData(This->_recQueueBuffer[0], noSamp10ms); + // push data + This->PushRecordingData(This->_recQueueBuffer[0], noSamp10ms); // enqueue new buffer SLresult slResult = (*This->m_slRecorderSimpleBufferQueue)->Enqueue( - This->m_slRecorderSimpleBufferQueue, - (void*) This->_recQueueBuffer[0], - (noSamp10ms << BYTES_PER_SAMPLE_LOG2)); + This->m_slRecorderSimpleBufferQueue, + (void*) This->_recQueueBuffer[0], + (noSamp10ms << BYTES_PER_SAMPLE_LOG2)); if (slResult != SL_RESULT_SUCCESS) { - AUDIO_OPENSLES_DEBUG_WARN("Failed to enqueue recording buffer with error code = %d", slResult); + AUDIO_OPENSLES_DEBUG_WARN("Failed to enqueue recording buffer with error code = %d", slResult); return; } #else unsigned int dataPos = 0; - uint16_t bufPos = 0; + uint16_t bufPos = 0; int16_t insertPos = -1; unsigned int nCopy = 0; // Number of samples to copy - while (dataPos < noSamp10ms) - { + while (dataPos < noSamp10ms) { // Loop over all recording buffers or until we find the partially // full buffer // First choice is to insert into partially full buffer, @@ -1068,24 +1096,20 @@ void SLAudioDevice::RecorderSimpleBufferQueueCallback(SLAndroidSimpleBufferQueue bufPos = 0; insertPos = -1; nCopy = 0; - while (bufPos < N_REC_BUFFERS) - { - if ((This->_recLength[bufPos] > 0) && (This->_recLength[bufPos] < noSamp10ms)) - { + while (bufPos < N_REC_BUFFERS) { + if ((This->_recLength[bufPos] > 0) && (This->_recLength[bufPos] < noSamp10ms)) { // Found the partially full buffer insertPos = static_cast<int16_t> (bufPos); bufPos = N_REC_BUFFERS; // Don't need to search more } - else if ((-1 == insertPos) && (0 == This->_recLength[bufPos])) - { + else if ((-1 == insertPos) && (0 == This->_recLength[bufPos])) { // Found an empty buffer insertPos = static_cast<int16_t> (bufPos); } ++bufPos; } - if (insertPos > -1) - { + if (insertPos > -1) { // We found a non-full buffer, copy data from the buffer queue // o recBuffer unsigned int dataToCopy = noSamp10ms - dataPos; @@ -1093,8 +1117,7 @@ void SLAudioDevice::RecorderSimpleBufferQueueCallback(SLAndroidSimpleBufferQueue unsigned int roomInBuffer = noSamp10ms - currentRecLen; nCopy = (dataToCopy < roomInBuffer ? dataToCopy : roomInBuffer); memcpy(&This->_recBuffer[insertPos][currentRecLen], &This->_recQueueBuffer[This->_recQueueSeq][dataPos], nCopy * sizeof(short)); - if (0 == currentRecLen) - { + if (0 == currentRecLen) { _recSeqNumber[insertPos] = This->_recCurrentSeq; ++_recCurrentSeq; } @@ -1104,8 +1127,7 @@ void SLAudioDevice::RecorderSimpleBufferQueueCallback(SLAndroidSimpleBufferQueue This->_recLength[insertPos] += nCopy; dataPos += nCopy; } - else - { + else { // Didn't find a non-full buffer AUDIO_OPENSLES_DEBUG_WARN("Could not insert into recording buffer"); dataPos = noSamp10ms; // Don't try to insert more @@ -1117,19 +1139,19 @@ void SLAudioDevice::RecorderSimpleBufferQueueCallback(SLAndroidSimpleBufferQueue memset(This->_recQueueBuffer[This->_recQueueSeq], 0, (REC_BUF_SIZE_IN_SAMPLES << BYTES_PER_SAMPLE_LOG2)); // write the empty buffer to the queue SLresult slResult = (*This->m_slRecorderSimpleBufferQueue)->Enqueue( - This->m_slRecorderSimpleBufferQueue, - (void*) This->_recQueueBuffer[This->_recQueueSeq], - (noSamp10ms << BYTES_PER_SAMPLE_LOG2)); + This->m_slRecorderSimpleBufferQueue, + (void*) This->_recQueueBuffer[This->_recQueueSeq], + (noSamp10ms << BYTES_PER_SAMPLE_LOG2)); if (slResult != SL_RESULT_SUCCESS) { - AUDIO_OPENSLES_DEBUG_WARN("Failed to enqueue recording buffer with error code = %d", slResult); + AUDIO_OPENSLES_DEBUG_WARN("Failed to enqueue recording buffer with error code = %d", slResult); return; } // update the rec queue seq This->_recQueueSeq = (This->_recQueueSeq + 1) % N_REC_QUEUE_BUFFERS; - // alert thread - // TODO + // alert thread + // TODO #endif } } diff --git a/plugins/audio_opensles/audio_opensles_device.h b/plugins/audio_opensles/audio_opensles_device.h index 7f24dac..dd7da73 100755 --- a/plugins/audio_opensles/audio_opensles_device.h +++ b/plugins/audio_opensles/audio_opensles_device.h @@ -1,17 +1,17 @@ /* Copyright (C) 2012 Doubango Telecom <http://www.doubango.org> -* +* * This file is part of Open Source Doubango Framework. * * DOUBANGO 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 3 of the License, or * (at your option) any later version. -* +* * DOUBANGO 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 DOUBANGO. */ @@ -50,7 +50,7 @@ public: const uint32_t nSamples, const uint8_t nBytesPerSample, const uint8_t nChannels, - const uint32_t samplesPerSec) = 0; + const uint32_t samplesPerSec) = 0; virtual int32_t NeedMorePlayData(const uint32_t nSamples, const uint8_t nBytesPerSample, @@ -66,75 +66,75 @@ protected: class SLAudioDevice { public: - SLAudioDevice(const SLAudioDeviceCallback* pCallback = NULL); - virtual ~SLAudioDevice(); + SLAudioDevice(const SLAudioDeviceCallback* pCallback = NULL); + virtual ~SLAudioDevice(); public: - int SetCallback(const SLAudioDeviceCallback* pCallback); - int Init(); - bool Initialized(); - int SpeakerIsAvailable(bool *pAvailable); - int InitSpeaker(); - int SetMaxSpeakerVolume(int nMaxSpeakerVolume); - int SetMinSpeakerVolume(int nMinSpeakerVolume); - int SetSpeakerVolume(int nSpeakerVolume); - int SetSpeakerOn(bool bSpeakerOn); - int PlayoutIsAvailable(bool *pAvailable); - int SetStereoPlayout(bool bEnabled); - int SetPlayoutBuffer(int nPlayoutBufferSize); - int SetPlayoutSampleRate(int nPlayoutSampleRate); - int InitPlayout(); - int StereoPlayout(bool *pEnabled); - int PlayoutSampleRate(int *pPlayoutSampleRate); - int StartPlayout(); - bool Playing(); - int StopPlayout(); - int RecordingIsAvailable(bool *pAvailable); - int MicrophoneIsAvailable(bool *pAvailable); - int InitMicrophone(); - int SetMicrophoneVolume(int nMicrophoneVolume); - int SetStereoRecording(bool bEnabled); - int SetRecordingSampleRate(int nRecordingSampleRate); - int InitRecording(); - int StereoRecording(bool *pEnabled); - int RecordingSampleRate(int *pRecordingSampleRate); - int StartRecording(); - bool Recording(); - int StopRecording(); - int Terminate(); + int SetCallback(const SLAudioDeviceCallback* pCallback); + int Init(); + bool Initialized(); + int SpeakerIsAvailable(bool *pAvailable); + int InitSpeaker(); + int SetMaxSpeakerVolume(int nMaxSpeakerVolume); + int SetMinSpeakerVolume(int nMinSpeakerVolume); + int SetSpeakerVolume(int nSpeakerVolume); + int SetSpeakerOn(bool bSpeakerOn); + int PlayoutIsAvailable(bool *pAvailable); + int SetStereoPlayout(bool bEnabled); + int SetPlayoutBuffer(int nPlayoutBufferSize); + int SetPlayoutSampleRate(int nPlayoutSampleRate); + int InitPlayout(); + int StereoPlayout(bool *pEnabled); + int PlayoutSampleRate(int *pPlayoutSampleRate); + int StartPlayout(); + bool Playing(); + int StopPlayout(); + int RecordingIsAvailable(bool *pAvailable); + int MicrophoneIsAvailable(bool *pAvailable); + int InitMicrophone(); + int SetMicrophoneVolume(int nMicrophoneVolume); + int SetStereoRecording(bool bEnabled); + int SetRecordingSampleRate(int nRecordingSampleRate); + int InitRecording(); + int StereoRecording(bool *pEnabled); + int RecordingSampleRate(int *pRecordingSampleRate); + int StartRecording(); + bool Recording(); + int StopRecording(); + int Terminate(); private: - int PlayoutApplyNewConfig(); - uint32_t PullPlayoutData(void* pAudioSamples, const uint32_t nSamples); - void PushRecordingData(void* pAudioSamples, const uint32_t nSamples); + int PlayoutApplyNewConfig(); + uint32_t PullPlayoutData(void* pAudioSamples, const uint32_t nSamples); + void PushRecordingData(void* pAudioSamples, const uint32_t nSamples); #if AUDIO_OPENSLES_UNDER_ANDROID - static void PlayerSimpleBufferQueueCallback(SLAndroidSimpleBufferQueueItf queueItf, void *pContext); - static void RecorderSimpleBufferQueueCallback(SLAndroidSimpleBufferQueueItf queueItf, void *pContext); + static void PlayerSimpleBufferQueueCallback(SLAndroidSimpleBufferQueueItf queueItf, void *pContext); + static void RecorderSimpleBufferQueueCallback(SLAndroidSimpleBufferQueueItf queueItf, void *pContext); #endif private: - const SLAudioDeviceCallback* m_pCallback; - int m_nMicDeviceId; - bool m_bInitialized; - bool m_bSpeakerInitialized; - bool m_bPlayoutInitialized; - bool m_bRecordingInitialized; - bool m_bMicrophoneInitialized; - bool m_bSpeakerOn; - bool m_bStereoPlayout; - bool m_bStereoRecording; - int m_nPlayoutBufferSize; - int m_nRecordingBufferSize; - int m_nPlayoutSampleRate; - int m_nRecordingSampleRate; - bool m_bPlaying; - bool m_bRecording; - int m_nSpeakerVolume; - int m_nMaxSpeakerVolume; - int m_nMinSpeakerVolume; + const SLAudioDeviceCallback* m_pCallback; + int m_nMicDeviceId; + bool m_bInitialized; + bool m_bSpeakerInitialized; + bool m_bPlayoutInitialized; + bool m_bRecordingInitialized; + bool m_bMicrophoneInitialized; + bool m_bSpeakerOn; + bool m_bStereoPlayout; + bool m_bStereoRecording; + int m_nPlayoutBufferSize; + int m_nRecordingBufferSize; + int m_nPlayoutSampleRate; + int m_nRecordingSampleRate; + bool m_bPlaying; + bool m_bRecording; + int m_nSpeakerVolume; + int m_nMaxSpeakerVolume; + int m_nMinSpeakerVolume; #if AUDIO_OPENSLES_UNDER_ANDROID - // audio unit + // audio unit SLObjectItf m_slEngineObject; // playout device @@ -152,10 +152,10 @@ private: SLAndroidSimpleBufferQueueItf m_slRecorderSimpleBufferQueue; SLDeviceVolumeItf m_slMicVolume; - int _recQueueSeq; + int _recQueueSeq; - // Playout buffer - uint8_t _playQueueBuffer[N_PLAY_QUEUE_BUFFERS][PLAY_BUF_SIZE_IN_SAMPLES << BYTES_PER_SAMPLE_LOG2]; + // Playout buffer + uint8_t _playQueueBuffer[N_PLAY_QUEUE_BUFFERS][PLAY_BUF_SIZE_IN_SAMPLES << BYTES_PER_SAMPLE_LOG2]; int _playQueueSeq; // Recording buffer uint8_t _recQueueBuffer[N_REC_QUEUE_BUFFERS][REC_BUF_SIZE_IN_SAMPLES << BYTES_PER_SAMPLE_LOG2]; diff --git a/plugins/audio_opensles/audio_opensles_device_impl.cxx b/plugins/audio_opensles/audio_opensles_device_impl.cxx index 8e32d91..69269aa 100755 --- a/plugins/audio_opensles/audio_opensles_device_impl.cxx +++ b/plugins/audio_opensles/audio_opensles_device_impl.cxx @@ -1,17 +1,17 @@ /* Copyright (C) 2012 Doubango Telecom <http://www.doubango.org> -* +* * This file is part of Open Source Doubango Framework. * * DOUBANGO 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 3 of the License, or * (at your option) any later version. -* +* * DOUBANGO 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 DOUBANGO. */ @@ -21,7 +21,7 @@ #include "audio_opensles_consumer.h" SLAudioDeviceCallbackImpl::SLAudioDeviceCallbackImpl(): -SLAudioDeviceCallback() + SLAudioDeviceCallback() { } @@ -30,29 +30,29 @@ SLAudioDeviceCallbackImpl::~SLAudioDeviceCallbackImpl() } int32_t SLAudioDeviceCallbackImpl::RecordedDataIsAvailable(const void* audioSamples, - const uint32_t nSamples, - const uint8_t nBytesPerSample, - const uint8_t nChannels, - const uint32_t samplesPerSec) + const uint32_t nSamples, + const uint8_t nBytesPerSample, + const uint8_t nChannels, + const uint32_t samplesPerSec) { - if(!m_pProducer){ - AUDIO_OPENSLES_DEBUG_WARN("No wrapped producer"); - return 0; - } - return audio_producer_opensles_handle_data_10ms(m_pProducer, audioSamples, nSamples, nBytesPerSample, samplesPerSec, nChannels); + if(!m_pProducer) { + AUDIO_OPENSLES_DEBUG_WARN("No wrapped producer"); + return 0; + } + return audio_producer_opensles_handle_data_10ms(m_pProducer, audioSamples, nSamples, nBytesPerSample, samplesPerSec, nChannels); } int32_t SLAudioDeviceCallbackImpl::NeedMorePlayData(const uint32_t nSamples, - const uint8_t nBytesPerSample, - const uint8_t nChannels, - const uint32_t samplesPerSec, - void* audioSamples, - uint32_t& nSamplesOut) + const uint8_t nBytesPerSample, + const uint8_t nChannels, + const uint32_t samplesPerSec, + void* audioSamples, + uint32_t& nSamplesOut) { - if(!m_pConsumer){ - AUDIO_OPENSLES_DEBUG_WARN("No wrapped consumer"); - return 0; - } - return audio_consumer_opensles_get_data_10ms(m_pConsumer, audioSamples, nSamples, nBytesPerSample, nChannels, samplesPerSec, nSamplesOut); + if(!m_pConsumer) { + AUDIO_OPENSLES_DEBUG_WARN("No wrapped consumer"); + return 0; + } + return audio_consumer_opensles_get_data_10ms(m_pConsumer, audioSamples, nSamples, nBytesPerSample, nChannels, samplesPerSec, nSamplesOut); }
\ No newline at end of file diff --git a/plugins/audio_opensles/audio_opensles_device_impl.h b/plugins/audio_opensles/audio_opensles_device_impl.h index 8168fe9..6f6ad60 100755 --- a/plugins/audio_opensles/audio_opensles_device_impl.h +++ b/plugins/audio_opensles/audio_opensles_device_impl.h @@ -1,17 +1,17 @@ /* Copyright (C) 2012 Doubango Telecom <http://www.doubango.org> -* +* * This file is part of Open Source Doubango Framework. * * DOUBANGO 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 3 of the License, or * (at your option) any later version. -* +* * DOUBANGO 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 DOUBANGO. */ @@ -24,14 +24,14 @@ class SLAudioDeviceCallbackImpl : public SLAudioDeviceCallback { public: - SLAudioDeviceCallbackImpl(); - virtual ~SLAudioDeviceCallbackImpl(); + SLAudioDeviceCallbackImpl(); + virtual ~SLAudioDeviceCallbackImpl(); - virtual int32_t RecordedDataIsAvailable(const void* audioSamples, + virtual int32_t RecordedDataIsAvailable(const void* audioSamples, const uint32_t nSamples, const uint8_t nBytesPerSample, const uint8_t nChannels, - const uint32_t samplesPerSec); + const uint32_t samplesPerSec); virtual int32_t NeedMorePlayData(const uint32_t nSamples, const uint8_t nBytesPerSample, @@ -40,12 +40,16 @@ public: void* audioSamples, uint32_t& nSamplesOut); - inline void SetConsumer(const struct audio_consumer_opensles_s* pConsumer){ m_pConsumer = pConsumer; } - inline void SetProducer(const struct audio_producer_opensles_s* pProducer){ m_pProducer = pProducer; } + inline void SetConsumer(const struct audio_consumer_opensles_s* pConsumer) { + m_pConsumer = pConsumer; + } + inline void SetProducer(const struct audio_producer_opensles_s* pProducer) { + m_pProducer = pProducer; + } private: - const struct audio_consumer_opensles_s* m_pConsumer; // mut be const and must not take reference - const struct audio_producer_opensles_s* m_pProducer; // mut be const and must not take reference + const struct audio_consumer_opensles_s* m_pConsumer; // mut be const and must not take reference + const struct audio_producer_opensles_s* m_pProducer; // mut be const and must not take reference }; #endif /* _DOUBANGO_AUDIO_OPENSLES_SLDEVICE_IMPL_H */ diff --git a/plugins/audio_opensles/audio_opensles_producer.cxx b/plugins/audio_opensles/audio_opensles_producer.cxx index 69c06f6..007b59f 100755 --- a/plugins/audio_opensles/audio_opensles_producer.cxx +++ b/plugins/audio_opensles/audio_opensles_producer.cxx @@ -1,17 +1,17 @@ /* Copyright (C) 2012 Doubango Telecom <http://www.doubango.org> -* +* * This file is part of Open Source Doubango Framework. * * DOUBANGO 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 3 of the License, or * (at your option) any later version. -* +* * DOUBANGO 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 DOUBANGO. */ @@ -24,159 +24,158 @@ #include "tsk_memory.h" #include "tsk_debug.h" -typedef struct audio_producer_opensles_s -{ - TDAV_DECLARE_PRODUCER_AUDIO; - - bool isMuted; - audio_opensles_instance_handle_t* audioInstHandle; - struct{ - void* ptr; - int size; - int index; - } buffer; +typedef struct audio_producer_opensles_s { + TDAV_DECLARE_PRODUCER_AUDIO; + + bool isMuted; + audio_opensles_instance_handle_t* audioInstHandle; + struct { + void* ptr; + int size; + int index; + } buffer; } audio_producer_opensles_t; int audio_producer_opensles_handle_data_10ms(const audio_producer_opensles_t* _self, const void* audioSamples, int nSamples, int nBytesPerSample, int samplesPerSec, int nChannels) { - if(!_self || !audioSamples || !nSamples){ - AUDIO_OPENSLES_DEBUG_ERROR("Invalid parameter"); - return -1; - } - if(!TMEDIA_PRODUCER(_self)->enc_cb.callback){ - AUDIO_OPENSLES_DEBUG_WARN("No callback function is registered for the producer"); - return 0; - } - if((nSamples != (samplesPerSec / 100))){ - AUDIO_OPENSLES_DEBUG_ERROR("Not producing 10ms samples (nSamples=%d, samplesPerSec=%d)", nSamples, samplesPerSec); - return -2; - } - if((nBytesPerSample != (TMEDIA_PRODUCER(_self)->audio.bits_per_sample >> 3))){ - AUDIO_OPENSLES_DEBUG_ERROR("%d not valid bytes/samples", nBytesPerSample); - return -3; - } - if((nChannels != TMEDIA_PRODUCER(_self)->audio.channels)){ - AUDIO_OPENSLES_DEBUG_ERROR("Recording - %d not the expected number of channels but should be %d", nChannels, TMEDIA_PRODUCER(_self)->audio.channels); - return -4; - } - - int nSamplesInBits = (nSamples * nBytesPerSample); - if(_self->buffer.index + nSamplesInBits > _self->buffer.size){ - AUDIO_OPENSLES_DEBUG_ERROR("Buffer overflow"); - return -5; - } - - audio_producer_opensles_t* self = const_cast<audio_producer_opensles_t*>(_self); - - if(self->isMuted){ - memset((((uint8_t*)self->buffer.ptr) + self->buffer.index), 0, nSamplesInBits); - } - else{ - memcpy((((uint8_t*)self->buffer.ptr) + self->buffer.index), audioSamples, nSamplesInBits); - } - self->buffer.index += nSamplesInBits; - - if(self->buffer.index == self->buffer.size){ - self->buffer.index = 0; - TMEDIA_PRODUCER(self)->enc_cb.callback(TMEDIA_PRODUCER(self)->enc_cb.callback_data, self->buffer.ptr, self->buffer.size); - } - - return 0; + if(!_self || !audioSamples || !nSamples) { + AUDIO_OPENSLES_DEBUG_ERROR("Invalid parameter"); + return -1; + } + if(!TMEDIA_PRODUCER(_self)->enc_cb.callback) { + AUDIO_OPENSLES_DEBUG_WARN("No callback function is registered for the producer"); + return 0; + } + if((nSamples != (samplesPerSec / 100))) { + AUDIO_OPENSLES_DEBUG_ERROR("Not producing 10ms samples (nSamples=%d, samplesPerSec=%d)", nSamples, samplesPerSec); + return -2; + } + if((nBytesPerSample != (TMEDIA_PRODUCER(_self)->audio.bits_per_sample >> 3))) { + AUDIO_OPENSLES_DEBUG_ERROR("%d not valid bytes/samples", nBytesPerSample); + return -3; + } + if((nChannels != TMEDIA_PRODUCER(_self)->audio.channels)) { + AUDIO_OPENSLES_DEBUG_ERROR("Recording - %d not the expected number of channels but should be %d", nChannels, TMEDIA_PRODUCER(_self)->audio.channels); + return -4; + } + + int nSamplesInBits = (nSamples * nBytesPerSample); + if(_self->buffer.index + nSamplesInBits > _self->buffer.size) { + AUDIO_OPENSLES_DEBUG_ERROR("Buffer overflow"); + return -5; + } + + audio_producer_opensles_t* self = const_cast<audio_producer_opensles_t*>(_self); + + if(self->isMuted) { + memset((((uint8_t*)self->buffer.ptr) + self->buffer.index), 0, nSamplesInBits); + } + else { + memcpy((((uint8_t*)self->buffer.ptr) + self->buffer.index), audioSamples, nSamplesInBits); + } + self->buffer.index += nSamplesInBits; + + if(self->buffer.index == self->buffer.size) { + self->buffer.index = 0; + TMEDIA_PRODUCER(self)->enc_cb.callback(TMEDIA_PRODUCER(self)->enc_cb.callback_data, self->buffer.ptr, self->buffer.size); + } + + return 0; } /* ============ Media Producer Interface ================= */ static int audio_producer_opensles_set(tmedia_producer_t* _self, const tmedia_param_t* param) -{ - audio_producer_opensles_t* self = (audio_producer_opensles_t*)_self; - if(param->plugin_type == tmedia_ppt_producer){ - if(param->value_type == tmedia_pvt_int32){ - if(tsk_striequals(param->key, "mute")){ - self->isMuted = (*((int32_t*)param->value) != 0); - // Mute not supported on android -> send silence when needed - return 0; - } - else if(tsk_striequals(param->key, "volume")){ - return audio_opensles_instance_set_microphone_volume(self->audioInstHandle, *((int32_t*)param->value)); - } - } - } - return tdav_producer_audio_set(TDAV_PRODUCER_AUDIO(self), param); +{ + audio_producer_opensles_t* self = (audio_producer_opensles_t*)_self; + if(param->plugin_type == tmedia_ppt_producer) { + if(param->value_type == tmedia_pvt_int32) { + if(tsk_striequals(param->key, "mute")) { + self->isMuted = (*((int32_t*)param->value) != 0); + // Mute not supported on android -> send silence when needed + return 0; + } + else if(tsk_striequals(param->key, "volume")) { + return audio_opensles_instance_set_microphone_volume(self->audioInstHandle, *((int32_t*)param->value)); + } + } + } + return tdav_producer_audio_set(TDAV_PRODUCER_AUDIO(self), param); } static int audio_producer_opensles_prepare(tmedia_producer_t* _self, const tmedia_codec_t* codec) { - audio_producer_opensles_t* self = (audio_producer_opensles_t*)_self; - if(!self || !codec){ - AUDIO_OPENSLES_DEBUG_ERROR("Invalid parameter"); - return -1; - } - - // create audio instance - if(!(self->audioInstHandle = audio_opensles_instance_create(TMEDIA_PRODUCER(self)->session_id))){ - AUDIO_OPENSLES_DEBUG_ERROR("Failed to create audio instance handle"); - return -2; - } - - // check that ptime is mutiple of 10 - if((codec->plugin->audio.ptime % 10)){ - AUDIO_OPENSLES_DEBUG_ERROR("ptime=%d not multiple of 10", codec->plugin->audio.ptime); - return -3; - } - - // init input parameters from the codec - TMEDIA_PRODUCER(self)->audio.channels = TMEDIA_CODEC_CHANNELS_AUDIO_ENCODING(codec); - TMEDIA_PRODUCER(self)->audio.rate = TMEDIA_CODEC_RATE_ENCODING(codec); - TMEDIA_PRODUCER(self)->audio.ptime = TMEDIA_CODEC_PTIME_AUDIO_ENCODING(codec); - - AUDIO_OPENSLES_DEBUG_INFO("audio_producer_opensles_prepare(channels=%d, rate=%d, ptime=%d)", codec->plugin->audio.channels, codec->plugin->rate, codec->plugin->audio.ptime); - - // prepare playout device and update output parameters - int ret; - ret = audio_opensles_instance_prepare_producer(self->audioInstHandle, &_self); - - // now that the producer is prepared we can initialize internal buffer using device caps - if(ret == 0){ - // allocate buffer - int xsize = ((TMEDIA_PRODUCER(self)->audio.ptime * TMEDIA_PRODUCER(self)->audio.rate) / 1000) * (TMEDIA_PRODUCER(self)->audio.bits_per_sample >> 3); - AUDIO_OPENSLES_DEBUG_INFO("producer buffer xsize = %d", xsize); - if(!(self->buffer.ptr = tsk_realloc(self->buffer.ptr, xsize))){ - AUDIO_OPENSLES_DEBUG_ERROR("Failed to allocate buffer with size = %d", xsize); - self->buffer.size = 0; - return -1; - } - self->buffer.size = xsize; - self->buffer.index = 0; - } - return ret; + audio_producer_opensles_t* self = (audio_producer_opensles_t*)_self; + if(!self || !codec) { + AUDIO_OPENSLES_DEBUG_ERROR("Invalid parameter"); + return -1; + } + + // create audio instance + if(!(self->audioInstHandle = audio_opensles_instance_create(TMEDIA_PRODUCER(self)->session_id))) { + AUDIO_OPENSLES_DEBUG_ERROR("Failed to create audio instance handle"); + return -2; + } + + // check that ptime is mutiple of 10 + if((codec->plugin->audio.ptime % 10)) { + AUDIO_OPENSLES_DEBUG_ERROR("ptime=%d not multiple of 10", codec->plugin->audio.ptime); + return -3; + } + + // init input parameters from the codec + TMEDIA_PRODUCER(self)->audio.channels = TMEDIA_CODEC_CHANNELS_AUDIO_ENCODING(codec); + TMEDIA_PRODUCER(self)->audio.rate = TMEDIA_CODEC_RATE_ENCODING(codec); + TMEDIA_PRODUCER(self)->audio.ptime = TMEDIA_CODEC_PTIME_AUDIO_ENCODING(codec); + + AUDIO_OPENSLES_DEBUG_INFO("audio_producer_opensles_prepare(channels=%d, rate=%d, ptime=%d)", codec->plugin->audio.channels, codec->plugin->rate, codec->plugin->audio.ptime); + + // prepare playout device and update output parameters + int ret; + ret = audio_opensles_instance_prepare_producer(self->audioInstHandle, &_self); + + // now that the producer is prepared we can initialize internal buffer using device caps + if(ret == 0) { + // allocate buffer + int xsize = ((TMEDIA_PRODUCER(self)->audio.ptime * TMEDIA_PRODUCER(self)->audio.rate) / 1000) * (TMEDIA_PRODUCER(self)->audio.bits_per_sample >> 3); + AUDIO_OPENSLES_DEBUG_INFO("producer buffer xsize = %d", xsize); + if(!(self->buffer.ptr = tsk_realloc(self->buffer.ptr, xsize))) { + AUDIO_OPENSLES_DEBUG_ERROR("Failed to allocate buffer with size = %d", xsize); + self->buffer.size = 0; + return -1; + } + self->buffer.size = xsize; + self->buffer.index = 0; + } + return ret; } static int audio_producer_opensles_start(tmedia_producer_t* _self) { - audio_producer_opensles_t* self = (audio_producer_opensles_t*)_self; - if(!self){ - AUDIO_OPENSLES_DEBUG_ERROR("Invalid parameter"); - return -1; - } - AUDIO_OPENSLES_DEBUG_INFO("audio_producer_opensles_start"); - - return audio_opensles_instance_start_producer(self->audioInstHandle); + audio_producer_opensles_t* self = (audio_producer_opensles_t*)_self; + if(!self) { + AUDIO_OPENSLES_DEBUG_ERROR("Invalid parameter"); + return -1; + } + AUDIO_OPENSLES_DEBUG_INFO("audio_producer_opensles_start"); + + return audio_opensles_instance_start_producer(self->audioInstHandle); } static int audio_producer_opensles_pause(tmedia_producer_t* self) { - return 0; + return 0; } static int audio_producer_opensles_stop(tmedia_producer_t* _self) { - audio_producer_opensles_t* self = (audio_producer_opensles_t*)_self; - if(!self){ - AUDIO_OPENSLES_DEBUG_ERROR("Invalid parameter"); - return -1; - } + audio_producer_opensles_t* self = (audio_producer_opensles_t*)_self; + if(!self) { + AUDIO_OPENSLES_DEBUG_ERROR("Invalid parameter"); + return -1; + } - return audio_opensles_instance_stop_producer(self->audioInstHandle); + return audio_opensles_instance_stop_producer(self->audioInstHandle); } @@ -186,54 +185,52 @@ static int audio_producer_opensles_stop(tmedia_producer_t* _self) /* constructor */ static tsk_object_t* audio_producer_opensles_ctor(tsk_object_t *_self, va_list * app) { - audio_producer_opensles_t *self = (audio_producer_opensles_t *)_self; - if(self){ - /* init base */ - tdav_producer_audio_init(TDAV_PRODUCER_AUDIO(self)); - /* init self */ - - } - return self; + audio_producer_opensles_t *self = (audio_producer_opensles_t *)_self; + if(self) { + /* init base */ + tdav_producer_audio_init(TDAV_PRODUCER_AUDIO(self)); + /* init self */ + + } + return self; } /* destructor */ static tsk_object_t* audio_producer_opensles_dtor(tsk_object_t *_self) -{ - audio_producer_opensles_t *self = (audio_producer_opensles_t *)_self; - if(self){ - /* stop */ - audio_producer_opensles_stop(TMEDIA_PRODUCER(self)); - /* deinit self */ - if(self->audioInstHandle){ - audio_opensles_instance_destroy(&self->audioInstHandle); - } - TSK_FREE(self->buffer.ptr); - - /* deinit base */ - tdav_producer_audio_deinit(TDAV_PRODUCER_AUDIO(self)); - } - - return self; +{ + audio_producer_opensles_t *self = (audio_producer_opensles_t *)_self; + if(self) { + /* stop */ + audio_producer_opensles_stop(TMEDIA_PRODUCER(self)); + /* deinit self */ + if(self->audioInstHandle) { + audio_opensles_instance_destroy(&self->audioInstHandle); + } + TSK_FREE(self->buffer.ptr); + + /* deinit base */ + tdav_producer_audio_deinit(TDAV_PRODUCER_AUDIO(self)); + } + + return self; } /* object definition */ -static const tsk_object_def_t audio_producer_opensles_def_s = -{ - sizeof(audio_producer_opensles_t), - audio_producer_opensles_ctor, - audio_producer_opensles_dtor, - tdav_producer_audio_cmp, +static const tsk_object_def_t audio_producer_opensles_def_s = { + sizeof(audio_producer_opensles_t), + audio_producer_opensles_ctor, + audio_producer_opensles_dtor, + tdav_producer_audio_cmp, }; /* plugin definition*/ -static const tmedia_producer_plugin_def_t audio_producer_opensles_plugin_def_s = -{ - &audio_producer_opensles_def_s, - - tmedia_audio, - "SLES audio producer", - - audio_producer_opensles_set, - audio_producer_opensles_prepare, - audio_producer_opensles_start, - audio_producer_opensles_pause, - audio_producer_opensles_stop +static const tmedia_producer_plugin_def_t audio_producer_opensles_plugin_def_s = { + &audio_producer_opensles_def_s, + + tmedia_audio, + "SLES audio producer", + + audio_producer_opensles_set, + audio_producer_opensles_prepare, + audio_producer_opensles_start, + audio_producer_opensles_pause, + audio_producer_opensles_stop }; const tmedia_producer_plugin_def_t *audio_producer_opensles_plugin_def_t = &audio_producer_opensles_plugin_def_s;
\ No newline at end of file diff --git a/plugins/audio_opensles/audio_opensles_producer.h b/plugins/audio_opensles/audio_opensles_producer.h index 0c4c756..d6ce9d9 100755 --- a/plugins/audio_opensles/audio_opensles_producer.h +++ b/plugins/audio_opensles/audio_opensles_producer.h @@ -1,17 +1,17 @@ /* Copyright (C) 2012 Doubango Telecom <http://www.doubango.org> -* +* * This file is part of Open Source Doubango Framework. * * DOUBANGO 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 3 of the License, or * (at your option) any later version. -* +* * DOUBANGO 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 DOUBANGO. */ diff --git a/plugins/audio_opensles/dllmain.cxx b/plugins/audio_opensles/dllmain.cxx index e6b34f4..295c340 100755 --- a/plugins/audio_opensles/dllmain.cxx +++ b/plugins/audio_opensles/dllmain.cxx @@ -1,17 +1,17 @@ /* Copyright (C) 2012 Doubango Telecom <http://www.doubango.org> -* +* * This file is part of Open Source Doubango Framework. * * DOUBANGO 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 3 of the License, or * (at your option) any later version. -* +* * DOUBANGO 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 DOUBANGO. */ @@ -20,16 +20,15 @@ BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved - ) + ) { - switch (ul_reason_for_call) - { - case DLL_PROCESS_ATTACH: - case DLL_THREAD_ATTACH: - case DLL_THREAD_DETACH: - case DLL_PROCESS_DETACH: - break; - } - return TRUE; + switch (ul_reason_for_call) { + case DLL_PROCESS_ATTACH: + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + break; + } + return TRUE; } |