Commit 749713a6 authored by Alexandre Savard's avatar Alexandre Savard

#8671: Move audio gain management in audiolayer

parent 8b402ee6
......@@ -87,6 +87,8 @@ AlsaLayer::AlsaLayer()
, is_capture_open_(false)
, audioThread_(NULL)
{
setCaptureGain(Manager::instance().audioPreference.getVolumemic());
setPlaybackGain(Manager::instance().audioPreference.getVolumespkr());
}
// Destructor
......@@ -573,7 +575,7 @@ void AlsaLayer::capture()
goto end;
}
adjustVolume(in, toGetSamples, Manager::instance().getSpkrVolume());
adjustVolume(in, toGetSamples, getCaptureGain());
if (resample) {
int outSamples = toGetSamples * ((double) audioSampleRate_ / mainBufferSampleRate);
......@@ -594,7 +596,6 @@ end:
void AlsaLayer::playback(int maxSamples)
{
unsigned short spkrVolume = Manager::instance().getSpkrVolume();
unsigned int mainBufferSampleRate = Manager::instance().getMainBuffer()->getInternalSamplingRate();
bool resample = audioSampleRate_ != mainBufferSampleRate;
......@@ -608,10 +609,12 @@ void AlsaLayer::playback(int maxSamples)
SFLDataFormat *out = (SFLDataFormat *) malloc(toPut);
if (tone)
tone->getNext(out, maxSamples, spkrVolume);
else if (file_tone && !ringtoneHandle_)
file_tone->getNext(out, maxSamples, spkrVolume);
if (tone) {
tone->getNext(out, maxSamples, getPlaybackGain());
}
else if (file_tone && !ringtoneHandle_) {
file_tone->getNext(out, maxSamples, getPlaybackGain());
}
else
memset(out, 0, toPut);
......@@ -636,7 +639,7 @@ void AlsaLayer::playback(int maxSamples)
SFLDataFormat *out = (SFLDataFormat*) malloc(toGet);
Manager::instance().getMainBuffer()->getData(out, toGet);
adjustVolume(out, toGet / sizeof(SFLDataFormat), spkrVolume);
adjustVolume(out, toGet / sizeof(SFLDataFormat), getPlaybackGain());
if (resample) {
int inSamples = toGet / sizeof(SFLDataFormat);
......@@ -659,8 +662,6 @@ void AlsaLayer::audioCallback()
notifyincomingCall();
unsigned short spkrVolume = Manager::instance().getSpkrVolume();
snd_pcm_wait(playbackHandle_, 20);
int playbackAvailSmpl = snd_pcm_avail_update(playbackHandle_);
......@@ -675,7 +676,7 @@ void AlsaLayer::audioCallback()
SFLDataFormat *out = (SFLDataFormat*) malloc(toGet);
urgentRingBuffer_.Get(out, toGet);
adjustVolume(out, toGet / sizeof(SFLDataFormat), spkrVolume);
adjustVolume(out, toGet / sizeof(SFLDataFormat), getPlaybackGain());
write(out, toGet, playbackHandle_);
free(out);
......@@ -693,8 +694,10 @@ void AlsaLayer::audioCallback()
SFLDataFormat *out = (SFLDataFormat *) malloc(ringtoneAvailBytes);
if (file_tone)
file_tone->getNext(out, ringtoneAvailSmpl, spkrVolume);
if (file_tone) {
DEBUG("playback gain %d", getPlaybackGain());
file_tone->getNext(out, ringtoneAvailSmpl, getPlaybackGain());
}
else
memset(out, 0, ringtoneAvailBytes);
......
......@@ -115,7 +115,7 @@ class AlsaLayer : public AudioLayer {
* @return int Its index
*/
int getAudioDeviceIndex(const std::string &description) const;
void playback(int maxSamples);
void capture();
......
......@@ -34,6 +34,9 @@
#include "audio/dcblocker.h"
#include "manager.h"
unsigned int AudioLayer::captureGain_ = 100;
unsigned int AudioLayer::playbackGain_ = 100;
AudioLayer::AudioLayer()
: isStarted_(false)
, urgentRingBuffer_(SIZEBUF, Call::DEFAULT_ID)
......@@ -50,7 +53,10 @@ AudioLayer::AudioLayer()
AudioLayer::~AudioLayer()
{
delete converter_;
if(converter_) {
delete converter_;
converter_ = NULL;
}
}
void AudioLayer::flushMain()
......
......@@ -105,7 +105,33 @@ class AudioLayer {
*/
void flushUrgent();
/**
* Set capture stream gain (microphone)
*/
void setCaptureGain(unsigned int gain) {
captureGain_ = gain;
}
/**
* Set capture stream gain (microphone)
*/
unsigned int getCaptureGain(void) {
return captureGain_;
}
/**
* Set playback stream gain (speaker)
*/
void setPlaybackGain(unsigned int gain) {
playbackGain_ = gain;
}
/**
* Get playback stream gain (speaker)
*/
unsigned int getPlaybackGain(void) {
return playbackGain_;
}
/**
* Get the sample rate of the audio layer
......@@ -128,6 +154,16 @@ class AudioLayer {
*/
void notifyincomingCall();
/**
* Gain applied to mic signal
*/
static unsigned int captureGain_;
/**
* Gain applied to playback signal
*/
static unsigned int playbackGain_;
protected:
/**
......@@ -150,8 +186,20 @@ class AudioLayer {
* Lock for the entire audio layer
*/
ost::Mutex mutex_;
/**
* Remove audio offset that can be introduced by certain cheap audio device
*/
DcBlocker dcblocker_;
/**
* Configuration file for this
*/
AudioPreference &audioPref;
/**
* Manage sampling rate conversion
*/
SamplerateConverter *converter_;
private:
......
......@@ -37,6 +37,7 @@
#include "managerimpl.h"
namespace {
void playback_callback(pa_stream* s, size_t bytes, void* userdata)
{
assert(s && bytes);
......@@ -307,6 +308,7 @@ void PulseLayer::writeToSpeaker()
pa_stream *s = playback_->pulseStream();
// available bytes to be written in pulseaudio internal buffer
int writable = pa_stream_writable_size(s);
......
......@@ -68,6 +68,7 @@ class PulseLayer : public AudioLayer {
virtual void stopStream();
private:
static void context_state_callback(pa_context* c, void* user_data);
static void context_changed_callback(pa_context* c,
......
......@@ -35,6 +35,7 @@
#include "sip/sipcall.h"
#include "sip/sipvoiplink.h"
#include "audio/audiolayer.h"
#include "audio/audiortp/audio_rtp_factory.h"
#include "audio/audiortp/audio_zrtp_session.h"
......@@ -128,10 +129,20 @@ void CallManager::attendedTransfer(const std::string& transferID, const std::str
void CallManager::setVolume(const std::string& device, const double& value)
{
if (device == "speaker")
Manager::instance().setSpkrVolume((int)(value * 100.0));
else if (device == "mic")
Manager::instance().setMicVolume((int)(value * 100.0));
AudioLayer *audiolayer = Manager::instance().getAudioDriver();
if(!audiolayer) {
ERROR("CallManager: Audio layer not valid while updating volume");
return;
}
DEBUG("DBUS set volume for %s: %f", device.c_str(), value);
if (device == "speaker") {
audiolayer->setPlaybackGain((int)(value * 100.0));
} else if (device == "mic") {
audiolayer->setCaptureGain((int)(value * 100.0));
}
volumeChanged(device, value);
}
......@@ -139,10 +150,17 @@ void CallManager::setVolume(const std::string& device, const double& value)
double
CallManager::getVolume(const std::string& device)
{
AudioLayer *audiolayer = Manager::instance().getAudioDriver();
if(!audiolayer) {
ERROR("CallManager: Audio layer not valid while updating volume");
return 0.0;
}
if (device == "speaker")
return Manager::instance().getSpkrVolume() / 100.0;
return audiolayer->getPlaybackGain() / 100.0;
else if (device == "mic")
return Manager::instance().getMicVolume() / 100.0;
return audiolayer->getCaptureGain() / 100.0;
return 0;
}
......
......@@ -73,8 +73,7 @@ ManagerImpl::ManagerImpl() :
hookPreference(), audioPreference(), shortcutPreferences(),
hasTriedToRegister_(false), audioCodecFactory(), dbus_(), config_(), currentCallId_(),
currentCallMutex_(), audiodriver_(0), dtmfKey_(0), toneMutex_(),
telephoneTone_(0), audiofile_(0), speakerVolume_(0), micVolume_(0),
audioLayerMutex_(), waitingCall_(), waitingCallMutex_(),
telephoneTone_(0), audiofile_(0), audioLayerMutex_(), waitingCall_(), waitingCallMutex_(),
nbIncomingWaitingCall_(0), path_(), callAccountMap_(),
callAccountMapMutex_(), IPToIPMap_(), accountMap_(),
mainBuffer_(), conferenceMap_(), history_(new History),
......@@ -118,7 +117,6 @@ void ManagerImpl::init(std::string config_file)
loadAccountMap(parser);
delete parser;
initVolume();
initAudioDriver();
{
......@@ -1248,8 +1246,11 @@ void ManagerImpl::removeStream(const std::string& call_id)
void ManagerImpl::saveConfig()
{
DEBUG("Manager: Saving Configuration to XDG directory %s", path_.c_str());
audioPreference.setVolumemic(getMicVolume());
audioPreference.setVolumespkr(getSpkrVolume());
AudioLayer *audiolayer = getAudioDriver();
if(audiolayer != NULL) {
audioPreference.setVolumemic(audiolayer->getCaptureGain());
audioPreference.setVolumespkr(audiolayer->getPlaybackGain());
}
try {
Conf::YamlEmitter emitter(path_.c_str());
......@@ -2320,26 +2321,6 @@ void ManagerImpl::audioSamplingRateChanged(int samplerate)
audiodriver_->startStream();
}
/**
* Init the volume for speakers/micro from 0 to 100 value
* Initialization: Main Thread
*/
void ManagerImpl::initVolume()
{
setSpkrVolume(audioPreference.getVolumespkr());
setMicVolume(audioPreference.getVolumemic());
}
void ManagerImpl::setSpkrVolume(unsigned short spkr_vol)
{
speakerVolume_ = spkr_vol;
}
void ManagerImpl::setMicVolume(unsigned short mic_vol)
{
micVolume_ = mic_vol;
}
int ManagerImpl::getLocalIp2IpPort() const
{
return preferences.getPortNum();
......
......@@ -849,42 +849,6 @@ class ManagerImpl {
*/
bool incomingCallWaiting() const;
/*
* Inline functions to manage speaker volume control
* Read by main thread and AudioLayer thread
* Write by main thread only
* @return unsigned short The volume value
*/
unsigned short getSpkrVolume() const {
return speakerVolume_;
}
/*
* Inline functions to manage speaker volume control
* Read by main thread and AudioLayer thread
* Write by main thread only
* @param spkr_vol The volume value
*/
void setSpkrVolume(unsigned short spkr_vol);
/*
* Inline functions to manage mic volume control
* Read by main thread and AudioLayer thread
* Write by main thread only
* @return unsigned short The volume value
*/
unsigned short getMicVolume() const {
return micVolume_;
}
/*
* Inline functions to manage mic volume control
* Read by main thread and AudioLayer thread
* Write by main thread only
* @param mic_vol The volume value
*/
void setMicVolume(unsigned short mic_vol);
/**
* Return a new random callid that is not present in the list
* @return std::string A brand new callid
......@@ -949,11 +913,6 @@ class ManagerImpl {
*/
void initZeroconf();
/*
* Init the volume for speakers/micro from 0 to 100 value
*/
void initVolume();
/**
* Switch of current call id
* @param id The new callid
......@@ -992,8 +951,8 @@ class ManagerImpl {
AudioFile *audiofile_;
// To handle volume control
short speakerVolume_;
short micVolume_;
// short speakerVolume_;
// short micVolume_;
// End of sound variable
/**
......
......@@ -602,14 +602,14 @@ select_audio_manager(void)
gtk_container_remove(GTK_CONTAINER(alsa_conf) , alsabox);
gtk_widget_hide(alsa_conf);
if (gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(volumeToggle_))) {
main_window_volume_controls(FALSE);
eel_gconf_set_integer(SHOW_VOLUME_CONTROLS, FALSE);
gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(volumeToggle_), FALSE);
}
gtk_action_set_sensitive(volumeToggle_, FALSE);
}
if (gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(volumeToggle_))) {
main_window_volume_controls(FALSE);
eel_gconf_set_integer(SHOW_VOLUME_CONTROLS, FALSE);
gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(volumeToggle_), FALSE);
}
}
void
......
......@@ -140,7 +140,7 @@
/** Behaviour of the main window on incoming calls */
#define __POPUP_WINDOW (eel_gconf_get_integer (POPUP_ON_CALL))
/** Show/Hide the volume controls */
#define SHOW_VOLUME (eel_gconf_get_integer (SHOW_VOLUME_CONTROLS) && must_show_alsa_conf())
#define SHOW_VOLUME (eel_gconf_get_integer (SHOW_VOLUME_CONTROLS))
/** DTMF type */
#define OVERRTP "overrtp"
......
......@@ -1577,7 +1577,7 @@ create_menus(GtkUIManager *ui_manager)
// Set the toggle buttons
gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(gtk_ui_manager_get_action(ui_manager, "/MenuBar/ViewMenu/Dialpad")), eel_gconf_get_boolean(CONF_SHOW_DIALPAD));
gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(volumeToggle_),(gboolean) SHOW_VOLUME);
gtk_action_set_sensitive(volumeToggle_, must_show_alsa_conf());
gtk_action_set_sensitive(volumeToggle_, TRUE);
gtk_action_set_sensitive(gtk_ui_manager_get_action(ui_manager, "/MenuBar/ViewMenu/Toolbar"), FALSE);
/* Add the loading icon at the right of the toolbar. It is used for addressbook searches. */
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment