Add audio-in set/get volume 51/223051/14 accepted/tizen/unified/20200218.145902 submit/tizen/20200217.053256 submit/tizen/20200217.171228
authorSeungbae Shin <seungbae.shin@samsung.com>
Wed, 22 Jan 2020 11:37:24 +0000 (20:37 +0900)
committerSeungbae Shin <seungbae.shin@samsung.com>
Mon, 10 Feb 2020 02:28:40 +0000 (11:28 +0900)
Change-Id: I281840bb01528f2903430fcd036a3c4812aec68c

include/CAudioInfo.h
include/CAudioInput.h
include/CPulseAudioClient.h
include/audio_io.h
include/cpp_audio_io.h
src/audio_io.c
src/cpp/CAudioInput.cpp
src/cpp/CPulseAudioClient.cpp
src/cpp/cpp_audio_io.cpp

index a74b7e4..6f89ccc 100644 (file)
@@ -114,6 +114,9 @@ namespace tizen_media_audio {
         static constexpr unsigned int MIN_SYSTEM_SAMPLERATE = 8000;
         static constexpr unsigned int MAX_SYSTEM_SAMPLERATE = 192000;
 
+        static constexpr double MIN_RECORD_VOLUME = 0.0;
+        static constexpr double MAX_RECORD_VOLUME = 2.0;
+
         /* Constructors */
         CAudioInfo();
         CAudioInfo(unsigned int sampleRate, EChannel channel, ESampleType sampleType, EAudioType audioType, int audioIndex);
index a27bf18..d36608a 100644 (file)
@@ -58,6 +58,9 @@ namespace tizen_media_audio {
         int peek(const void** buffer, size_t* length);
         int drop();
 
+        void setVolume(double volume);
+        double getVolume();
+
     private:
         /* Private Methods */
         void __setInit(bool flag) noexcept;
@@ -66,6 +69,8 @@ namespace tizen_media_audio {
 
         bool __mIsUsedSyncRead;
         bool __mIsInit;
+
+        double __mVolume;
     };
 
 
index 4eb774f..01e33fb 100644 (file)
@@ -74,6 +74,8 @@ namespace tizen_media_audio {
         pa_usec_t getLatency();
         pa_usec_t getFinalLatency();
 
+        void applyRecordVolume(double volume);
+
     private:
         /* Members */
         EStreamDirection      __mDirection;
@@ -100,7 +102,7 @@ namespace tizen_media_audio {
 
         /* Private Method */
 
-        /* Private Calblack Method */
+        /* Private Callback Method */
         static void __contextStateChangeCb(pa_context* c, void* user_data);
         static void __streamStateChangeCb(pa_stream* s, void* user_data);
         static void __streamCaptureCb(pa_stream* s, size_t length, void* user_data);
@@ -112,6 +114,8 @@ namespace tizen_media_audio {
         static void __successStreamCb(pa_stream* s, int success, void* user_data);
         static void __successDrainCb(pa_stream* s, int success, void* user_data);
         static void __successDrainCbInThread(pa_stream* s, int success, void* user_data);
+        static void __successVolumeCb(pa_context* c, int success, void* user_data);
+
     };
 
 
index 53e8b0e..421b0d5 100644 (file)
@@ -557,6 +557,48 @@ int audio_in_set_state_changed_cb(audio_in_h input, audio_in_state_changed_cb ca
 int audio_in_unset_state_changed_cb(audio_in_h input);
 
 /**
+ * @brief Gets the volume of the audio input data stream.
+ *
+ * @since_tizen 6.0
+ *
+ * @remarks The default @a volume of the audio input stream is 1.0.
+ *
+ * @param[in] input The handle to the audio input
+ * @param[out] volume The current volume value of the audio input stream
+ * @return @c 0 on success,
+ *         otherwise a negative error value
+ * @retval #AUDIO_IO_ERROR_NONE Successful
+ * @retval #AUDIO_IO_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #AUDIO_IO_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @see audio_in_set_volume()
+ */
+int audio_in_get_volume(audio_in_h input, double *volume);
+
+/**
+ * @brief Sets the volume of the audio input data stream.
+ *
+ * @since_tizen 6.0
+ *
+ * @remarks The default @a volume of the audio input stream is 1.0.
+ *          If the @a volume is less than 1.0, the loudness of recorded data will be decreased.
+ *          If the @a volume is greater than 1.0, the loudness of recorded data will be increased,
+ *          which can be useful when the loudness of original recorded data is too low in certain environments.
+ *          Note that the volume can be clipped if the @a volume is greater than 1.0 and the loudness of original recorded data is high enough.
+ *
+ * @param[in] input The handle to the audio input
+ * @param[in] volume The volume value to be set (0.0 <= volume <= 2.0)
+ * @return @c 0 on success,
+ *         otherwise a negative error value
+ * @retval #AUDIO_IO_ERROR_NONE Successful
+ * @retval #AUDIO_IO_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #AUDIO_IO_ERROR_NOT_SUPPORTED Not supported
+ *
+ * @see audio_in_get_volume()
+ */
+int audio_in_set_volume(audio_in_h input, double volume);
+
+/**
  * @}
  */
 
index 9b9e92d..2164d2f 100644 (file)
@@ -45,7 +45,8 @@ int cpp_audio_in_peek(audio_in_h input, const void **buffer, unsigned int *lengt
 int cpp_audio_in_drop(audio_in_h input);
 int cpp_audio_in_set_state_changed_cb(audio_in_h input, audio_in_state_changed_cb callback, void* user_data);
 int cpp_audio_in_unset_state_changed_cb(audio_in_h input);
-
+int cpp_audio_in_get_volume(audio_in_h input, double *volume);
+int cpp_audio_in_set_volume(audio_in_h input, double volume);
 
 int cpp_audio_out_create_new(int sample_rate, audio_channel_e channel, audio_sample_type_e type, audio_out_h *output);
 int cpp_audio_out_destroy(audio_out_h output);
index af5ebb3..f25068b 100644 (file)
@@ -118,6 +118,16 @@ int audio_in_unset_state_changed_cb(audio_in_h input)
        return cpp_audio_in_unset_state_changed_cb(input);
 }
 
+int audio_in_get_volume(audio_in_h input, double *volume)
+{
+       return cpp_audio_in_get_volume(input, volume);
+}
+
+int audio_in_set_volume(audio_in_h input, double volume)
+{
+       return cpp_audio_in_set_volume(input, volume);
+}
+
 /* Audio Out */
 int audio_out_create_new(int sample_rate, audio_channel_e channel, audio_sample_type_e type, audio_out_h *output)
 {
index 8b6633f..69cbd67 100644 (file)
@@ -33,7 +33,8 @@ using namespace tizen_media_audio;
 CAudioInput::CAudioInput(CAudioInfo& info) :
     CAudioIO(info),
     __mIsUsedSyncRead(true),
-    __mIsInit(false) {
+    __mIsInit(false),
+    __mVolume(1.0) {
     mDirection = CAudioInfo::EAudioDirection::AUDIO_DIRECTION_IN;
 }
 
@@ -103,6 +104,7 @@ void CAudioInput::finalize() {
     CAudioIO::finalize();
 
     __setInit(false);
+    __mVolume = 1.0;
 }
 
 void CAudioInput::prepare() {
@@ -135,6 +137,7 @@ void CAudioInput::prepare() {
         internalLock();
         mpPulseAudioClient = new CPulseAudioClient(CPulseAudioClient::EStreamDirection::STREAM_DIRECTION_RECORD, spec, this);
         mpPulseAudioClient->initialize();
+        mpPulseAudioClient->applyRecordVolume(__mVolume);
 #ifndef DISABLE_MOBILE_BACK_COMP
         /* Uncork stream which is created with CORKED flag */
         mpPulseAudioClient->cork(false);
@@ -317,3 +320,34 @@ int CAudioInput::drop() {
 
     return mpPulseAudioClient->drop();
 }
+
+void CAudioInput::setVolume(double volume) {
+    if (!__IsInit())
+        THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Not initialized"); //LCOV_EXCL_LINE
+
+    AUDIO_IO_LOGE("%d, %p", __IsInit(), mpPulseAudioClient);
+    try {
+        if (__IsReady()) {
+            if (mpPulseAudioClient->isInThread()) {
+                mpPulseAudioClient->applyRecordVolume(volume);
+            } else {
+                internalLock();
+                mpPulseAudioClient->applyRecordVolume(volume);
+                internalUnlock();
+            }
+        }
+    } catch (const CAudioError& e) {
+        if (!mpPulseAudioClient->isInThread())
+            internalUnlock();
+        throw;
+    }
+
+    __mVolume = volume;
+}
+
+double CAudioInput::getVolume() {
+    if (!__IsInit())
+        THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Not initialized"); //LCOV_EXCL_LINE
+
+    return __mVolume;
+}
\ No newline at end of file
index 2b598d7..ed65bf1 100644 (file)
@@ -282,6 +282,10 @@ void CPulseAudioClient::__successDrainCb(pa_stream* s, int success, void* user_d
     pa_threaded_mainloop_signal(pClient->__mpMainloop, 0);
 }
 
+void CPulseAudioClient::__successVolumeCb(pa_context *c, int success, void *user_data) {
+    AUDIO_IO_LOGD("pa_context[%p], success[%d], user_data[%p]", c, success, user_data);
+}
+
 void CPulseAudioClient::initialize() {
     if (__mIsInit)
         return;
@@ -1006,3 +1010,33 @@ pa_usec_t CPulseAudioClient::getFinalLatency() {
     return ret;
 }
 //LCOV_EXCL_STOP
+
+void CPulseAudioClient::applyRecordVolume(double volume) {
+    if (!__mIsInit)
+        THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Did not initialize CPulseAudioClient");
+
+    checkRunningState();
+
+    if (__mDirection != EStreamDirection::STREAM_DIRECTION_RECORD)
+        THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_SUPPORTED, "The Playback client can't use this function"); //LCOV_EXCL_LINE
+
+    try {
+        if (!isInThread())
+            pa_threaded_mainloop_lock(__mpMainloop);
+
+        pa_cvolume cv = { 0, };
+        pa_volume_t v = PA_VOLUME_NORM * volume;
+
+        pa_cvolume_set(&cv, __mSpec.getChannelMap().channels, v);
+
+        pa_operation_unref(pa_context_set_source_output_volume(__mpContext,
+                pa_stream_get_index(__mpStream), &cv, __successVolumeCb, NULL));
+
+        if (!isInThread())
+            pa_threaded_mainloop_unlock(__mpMainloop);
+    } catch (const CAudioError& e) {
+        if (!isInThread())
+            pa_threaded_mainloop_unlock(__mpMainloop);
+        throw;
+    }
+}
\ No newline at end of file
index 7161e53..223eed7 100644 (file)
@@ -767,7 +767,7 @@ int cpp_audio_in_unset_state_changed_cb(audio_in_h input) {
     try {
         if (!handle)
             THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
-                                   "Parameters are NULL output:%p", input);
+                                   "Parameters are NULL input:%p", input);
         assert(handle->audioIoHandle);
         AUDIO_IO_LOGD("[%p]", handle);
 
@@ -787,6 +787,59 @@ int cpp_audio_in_unset_state_changed_cb(audio_in_h input) {
     return AUDIO_IO_ERROR_NONE;
 }
 
+int cpp_audio_in_get_volume(audio_in_h input, double *volume) {
+    auto handle = static_cast<audio_io_s*>(input);
+
+    try {
+        if (!handle || !volume)
+            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
+                                   "Parameters are NULL input:%p, volume:%p", input, volume);
+        assert(handle->audioIoHandle);
+        AUDIO_IO_LOGD("[%p]", handle);
+
+        auto input_handle = dynamic_cast<CAudioInput*>(handle->audioIoHandle);
+        if (input_handle == nullptr)
+            return __convert_audio_io_error(CAudioError::EError::ERROR_INVALID_HANDLE);
+
+        *volume = input_handle->getVolume();
+    } catch (const CAudioError& e) {
+        AUDIO_IO_LOGE("%s", e.getErrorMsg());
+        return __convert_audio_io_error(e.getError());
+    }
+
+    AUDIO_IO_LOGD("[%p] done", handle);
+
+    return AUDIO_IO_ERROR_NONE;
+}
+
+int cpp_audio_in_set_volume(audio_in_h input, double volume) {
+    auto handle = static_cast<audio_io_s*>(input);
+
+    try {
+        if (!handle)
+            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT,
+                                   "Parameters are NULL input:%p", input);
+
+        if (volume < CAudioInfo::MIN_RECORD_VOLUME || volume > CAudioInfo::MAX_RECORD_VOLUME)
+            THROW_ERROR_MSG_FORMAT(CAudioError::EError::ERROR_INVALID_ARGUMENT, "Invalid volume: %f", volume);
+
+        assert(handle->audioIoHandle);
+        AUDIO_IO_LOGD("[%p]", handle);
+
+        auto input_handle = dynamic_cast<CAudioInput*>(handle->audioIoHandle);
+        if (input_handle == nullptr)
+            return __convert_audio_io_error(CAudioError::EError::ERROR_INVALID_HANDLE);
+
+        input_handle->setVolume(volume);
+    } catch (const CAudioError& e) {
+        AUDIO_IO_LOGE("%s", e.getErrorMsg());
+        return __convert_audio_io_error(e.getError());
+    }
+
+    AUDIO_IO_LOGD("[%p] done", handle);
+
+    return AUDIO_IO_ERROR_NONE;
+}
 
 /**
  * Audio Out