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);
int peek(const void** buffer, size_t* length);
int drop();
+ void setVolume(double volume);
+ double getVolume();
+
private:
/* Private Methods */
void __setInit(bool flag) noexcept;
bool __mIsUsedSyncRead;
bool __mIsInit;
+
+ double __mVolume;
};
pa_usec_t getLatency();
pa_usec_t getFinalLatency();
+ void applyRecordVolume(double volume);
+
private:
/* Members */
EStreamDirection __mDirection;
/* 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);
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);
+
};
*/
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);
+
/**
* @}
*/
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);
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)
{
CAudioInput::CAudioInput(CAudioInfo& info) :
CAudioIO(info),
__mIsUsedSyncRead(true),
- __mIsInit(false) {
+ __mIsInit(false),
+ __mVolume(1.0) {
mDirection = CAudioInfo::EAudioDirection::AUDIO_DIRECTION_IN;
}
CAudioIO::finalize();
__setInit(false);
+ __mVolume = 1.0;
}
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);
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
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;
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
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);
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