Commit 69e13254 authored by Alexandre Savard's avatar Alexandre Savard
Browse files

Merge branch 'm_savard' into echocancel

Conflicts:
	sflphone-common/src/audio/alsa/alsalayer.cpp
parents 9e76a5d6 2345dd70
......@@ -94,7 +94,7 @@ void preferences_dialog_fill_codec_list (account_t **a) {
* Fill store with output audio plugins
*/
void
preferences_dialog_fill_output_audio_plugin_list()
preferences_dialog_fill_audio_plugin_list()
{
GtkTreeIter iter;
gchar** list;
......@@ -103,7 +103,7 @@ preferences_dialog_fill_output_audio_plugin_list()
gtk_list_store_clear(pluginlist);
// Call dbus to retreive list
list = dbus_get_output_audio_plugin_list();
list = dbus_get_audio_plugin_list();
// For each API name included in list
int c = 0;
......@@ -235,7 +235,7 @@ select_active_ringtone_audio_device()
// Select active ringtone device on server
devices = dbus_get_current_audio_devices_index();
currentDeviceIndex = atoi(devices[0]);
currentDeviceIndex = atoi(devices[2]);
DEBUG("audio device index for ringtone = %d", currentDeviceIndex);
model = gtk_combo_box_get_model(GTK_COMBO_BOX(ringtone));
......@@ -787,7 +787,7 @@ GtkWidget* alsa_box()
gtk_widget_show( item );
// Set choices of audio managers
pluginlist = gtk_list_store_new(1, G_TYPE_STRING);
preferences_dialog_fill_output_audio_plugin_list();
preferences_dialog_fill_audio_plugin_list();
plugin = gtk_combo_box_new_with_model(GTK_TREE_MODEL(pluginlist));
select_active_output_audio_plugin();
gtk_label_set_mnemonic_widget(GTK_LABEL(item), plugin);
......
......@@ -466,17 +466,7 @@
<!-- Audio devices methods -->
<method name="getInputAudioPluginList" tp:name-for-bindings="getInputAudioPluginList">
<tp:docstring>
</tp:docstring>
<annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="VectorString"/>
<arg type="as" name="list" direction="out">
<tp:docstring>
</tp:docstring>
</arg>
</method>
<method name="getOutputAudioPluginList" tp:name-for-bindings="getOutputAudioPluginList">
<method name="getAudioPluginList" tp:name-for-bindings="getAudioPluginList">
<tp:docstring>
</tp:docstring>
<annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="VectorString"/>
......
......@@ -1297,44 +1297,27 @@ dbus_set_active_codec_list(const gchar** list, const gchar *accountID)
}
}
/**
* Get a list of input supported audio plugins
*/
gchar**
dbus_get_input_audio_plugin_list()
{
gchar** array;
GError* error = NULL;
org_sflphone_SFLphone_ConfigurationManager_get_input_audio_plugin_list(
configurationManagerProxy, &array, &error);
if (error)
{
ERROR("Failed to call get_input_audio_plugin_list() on ConfigurationManager: %s", error->message);
g_error_free(error);
}
return array;
}
/**
* Get a list of output supported audio plugins
*/
gchar**
dbus_get_output_audio_plugin_list()
dbus_get_audio_plugin_list()
{
gchar** array;
GError* error = NULL;
if (!org_sflphone_SFLphone_ConfigurationManager_get_output_audio_plugin_list(
if (!org_sflphone_SFLphone_ConfigurationManager_get_audio_plugin_list(
configurationManagerProxy, &array, &error))
{
if (error->domain == DBUS_GERROR && error->code
== DBUS_GERROR_REMOTE_EXCEPTION)
{
ERROR ("Caught remote method (get_output_audio_plugin_list) exception %s: %s", dbus_g_error_get_name(error), error->message);
ERROR ("Caught remote method (get_output_plugin_list) exception %s: %s", dbus_g_error_get_name(error), error->message);
}
else
{
ERROR("Error while calling get_out_audio_plugin_list: %s", error->message);
ERROR("Error while calling get_out_plugin_list: %s", error->message);
}
g_error_free(error);
return NULL;
......
......@@ -241,17 +241,11 @@ void dbus_set_active_codec_list (const gchar** list, const gchar*);
*/
gchar* dbus_get_current_codec_name(const callable_obj_t * c);
/**
* ConfigurationManager - Get the list of available input audio plugins
* @return gchar** The list of plugins
*/
gchar** dbus_get_input_audio_plugin_list();
/**
* ConfigurationManager - Get the list of available output audio plugins
* @return gchar** The list of plugins
*/
gchar** dbus_get_output_audio_plugin_list();
gchar** dbus_get_audio_plugin_list();
/**
* ConfigurationManager - Select an input audio plugin
......
/*
* Copyright (C) 2008 2009 Savoir-Faire Linux inc.
* Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com>
* Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -147,9 +148,27 @@ AlsaLayer::startStream (void)
if(_echoCanceller)
_echoCanceller->resetAlgorithm();
std::string pcmp = buildDeviceTopo (_audioPlugin, _indexOut, 0);
std::string pcmc = buildDeviceTopo (_audioPlugin, _indexIn, 0);
std::string pcmr = buildDeviceTopo (_audioPlugin, _indexRing, 0);
if(is_playback_running() && is_capture_running() )
return;
std::string pcmp;
std::string pcmr;
std::string pcmc;
if(_audioPlugin == PCM_DMIX_DSNOOP) {
pcmp = buildDeviceTopo (PCM_DMIX, _indexOut, 0);
pcmr = buildDeviceTopo (PCM_DMIX, _indexRing, 0);
pcmc = buildDeviceTopo(PCM_DSNOOP, _indexIn, 0);
}
else {
pcmp = buildDeviceTopo (_audioPlugin, _indexOut, 0);
pcmr = buildDeviceTopo (_audioPlugin, _indexRing, 0);
pcmc = buildDeviceTopo(_audioPlugin, _indexIn, 0);
}
_debug("pcmp: %s, index %d", pcmp.c_str(), _indexOut);
_debug("pcmr: %s, index %d", pcmr.c_str(), _indexRing);
_debug("pcmc: %s, index %d", pcmc.c_str(), _indexIn);
if (!is_playback_open()) {
open_device (pcmp, pcmc, pcmr, SFL_PCM_PLAYBACK);
......@@ -323,9 +342,11 @@ void AlsaLayer::closePlaybackStream (void)
_debug("Audio: Close ALSA playback");
if((err = snd_pcm_close(_RingtoneHandle)) < 0) {
_warn("Audio: Error: Closing ALSA ringtone: %s", snd_strerror(err));
}
if(_RingtoneHandle) {
if((err = snd_pcm_close(_RingtoneHandle)) < 0) {
_warn("Audio: Error: Closing ALSA ringtone: %s", snd_strerror(err));
}
}
if ( (err = snd_pcm_close (_PlaybackHandle)) < 0)
_warn("Audio: Error: Closing ALSA playback: %s", snd_strerror (err));
......@@ -539,15 +560,18 @@ AlsaLayer::open_device (std::string pcm_p, std::string pcm_c, std::string pcm_r,
return false;
}
if((err = snd_pcm_open(&_RingtoneHandle, pcm_r.c_str(), SND_PCM_STREAM_PLAYBACK, 0)) < 0) {
_warn("Audio: Error: Opening ringtone device %s", pcm_r.c_str());
// setErrorMessage(ALSA_RINGTONE_DEVICE);
}
if (getIndexOut() != getIndexRing()) {
if((err = snd_pcm_open(&_RingtoneHandle, pcm_r.c_str(), SND_PCM_STREAM_PLAYBACK, 0)) < 0) {
_warn("Audio: Error: Opening ringtone device %s", pcm_r.c_str());
// setErrorMessage(ALSA_RINGTONE_DEVICE);
}
if(!alsa_set_params(_RingtoneHandle, 1, getSampleRate())) {
_warn("Audio: Error: Ringtone failed");
snd_pcm_close(_RingtoneHandle);
if(!alsa_set_params(_RingtoneHandle, 1, getSampleRate())) {
_warn("Audio: Error: Ringtone failed");
snd_pcm_close(_RingtoneHandle);
}
}
open_playback ();
......@@ -604,9 +628,9 @@ AlsaLayer::write (void* buffer, int length, snd_pcm_t * handle)
case -EIO:
//_debugAlsa(" XRUN playback ignored (%s)", snd_strerror(err));
handle_xrun_playback();
handle_xrun_playback(handle);
if (snd_pcm_writei (_PlaybackHandle , buffer , frames) <0)
if (snd_pcm_writei (handle, buffer , frames) <0)
_debugAlsa ("Audio: XRUN handling failed");
_trigger_request = true;
......@@ -674,6 +698,7 @@ AlsaLayer::read (void* buffer, int toCopy)
void
AlsaLayer::handle_xrun_capture (void)
{
_debugAlsa ("Audio: Handle xrun capture");
snd_pcm_status_t* status;
snd_pcm_status_alloca (&status);
......@@ -687,22 +712,25 @@ AlsaLayer::handle_xrun_capture (void)
startCaptureStream ();
}
} else
_debugAlsa (" Get status failed");
_debugAlsa ("Audio: Get status failed");
}
void
AlsaLayer::handle_xrun_playback (void)
AlsaLayer::handle_xrun_playback (snd_pcm_t *handle)
{
_debugAlsa ("Audio: Handle xrun playback");
int state;
snd_pcm_status_t* status;
snd_pcm_status_alloca (&status);
if ( (state = snd_pcm_status (_PlaybackHandle, status)) < 0) _debugAlsa ("Audio: Error: Cannot get playback handle status (%s)" , snd_strerror (state));
if ( (state = snd_pcm_status (handle, status)) < 0)
_debugAlsa ("Audio: Error: Cannot get playback handle status (%s)" , snd_strerror (state));
else {
state = snd_pcm_status_get_state (status);
if (state == SND_PCM_STATE_XRUN) {
_debug("Audio: audio device in state SND_PCM_STATE_XRUN, restart device");
stopPlaybackStream ();
preparePlaybackStream ();
......@@ -715,10 +743,10 @@ AlsaLayer::handle_xrun_playback (void)
std::string
AlsaLayer::buildDeviceTopo (std::string plugin, int card, int subdevice)
{
std::string pcm = plugin;
std::stringstream ss,ss1;
std::string pcm = plugin;
if (pcm == "default" || pcm == "pulse")
if (pcm == PCM_DEFAULT)
return pcm;
ss << card;
......@@ -850,16 +878,25 @@ void AlsaLayer::audioCallback(void)
spkrVolume = _manager->getSpkrVolume();
micVolume = _manager->getMicVolume();
tone = _manager->getTelephoneTone();
file_tone = _manager->getTelephoneFile();
// AvailForGet tell the number of chars inside the buffer
// framePerBuffer are the number of data for one channel (left)
urgentAvailBytes = _urgentRingBuffer.AvailForGet();
//
if(!_PlaybackHandle)
return;
int playbackAvailSmpl = snd_pcm_avail_update(_PlaybackHandle);
int playbackAvailBytes = playbackAvailSmpl*sizeof(SFLDataFormat);
// _debug("PLAYBACK: %d", playbackAvailSmpl);
if (urgentAvailBytes > 0) {
// Urgent data (dtmf, incoming call signal) come first.
toGet = (urgentAvailBytes < (int) (framesPerBufferAlsa * sizeof (SFLDataFormat))) ? urgentAvailBytes : framesPerBufferAlsa * sizeof (SFLDataFormat);
out = (SFLDataFormat*) malloc (toGet * sizeof (SFLDataFormat));
toGet = (urgentAvailBytes < (int) (playbackAvailBytes)) ? urgentAvailBytes : playbackAvailBytes;
out = (SFLDataFormat*) malloc (toGet);
_urgentRingBuffer.Get (out, toGet, spkrVolume);
/* Play the sound */
......@@ -873,58 +910,44 @@ void AlsaLayer::audioCallback(void)
} else {
tone = _manager->getTelephoneTone();
file_tone = _manager->getTelephoneFile();
toGet = framesPerBufferAlsa;
maxBytes = toGet * sizeof (SFLDataFormat);
if (tone) {
if (tone != 0) {
out = (SFLDataFormat*) malloc (maxBytes * sizeof (SFLDataFormat));
tone->getNext (out, toGet, spkrVolume);
write (out , maxBytes, _PlaybackHandle);
out = (SFLDataFormat *) malloc (playbackAvailBytes);
tone->getNext (out, playbackAvailSmpl, spkrVolume);
write (out , playbackAvailBytes, _PlaybackHandle);
free (out);
out = 0;
}
else if (file_tone && !_RingtoneHandle) {
/*
} else if (file_tone != 0) {
out = (SFLDataFormat*) malloc (maxBytes * sizeof (SFLDataFormat));
file_tone->getNext (out, toGet, spkrVolume);
write (out , maxBytes, _PlaybackHandle);
out = (SFLDataFormat *) malloc (playbackAvailBytes);
file_tone->getNext (out, playbackAvailSmpl, spkrVolume);
write (out, playbackAvailBytes, _PlaybackHandle);
free (out);
out = 0;
free (out);
out = NULL;
} else {
*/
} else {
// If nothing urgent, play the regular sound samples
int _mainBufferSampleRate = getMainBuffer()->getInternalSamplingRate();
int maxNbSamplesToGet = 0;
int maxNbBytesToGet = 0;
int maxNbSamplesToGet = playbackAvailSmpl;
int maxNbBytesToGet = playbackAvailBytes;
// Compute maximal value to get into the ring buffer
if (_mainBufferSampleRate && ( (int) _audioSampleRate != _mainBufferSampleRate)) {
double upsampleFactor = (double) _audioSampleRate / _mainBufferSampleRate;
maxNbSamplesToGet = (int) ( (double) playbackAvailSmpl / upsampleFactor);
maxNbBytesToGet = maxNbSamplesToGet * sizeof (SFLDataFormat);
maxNbSamplesToGet = (int) ( (double) framesPerBufferAlsa / upsampleFactor);
}
} else {
maxNbSamplesToGet = framesPerBufferAlsa;
}
maxNbBytesToGet = maxNbSamplesToGet * sizeof (SFLDataFormat);
normalAvailBytes = getMainBuffer()->availForGet();
toGet = (normalAvailBytes < (int) maxNbBytesToGet) ? normalAvailBytes : maxNbBytesToGet;
......@@ -945,7 +968,7 @@ void AlsaLayer::audioCallback(void)
if (_mainBufferSampleRate && ( (int) _audioSampleRate != _mainBufferSampleRate)) {
rsmpl_out = (SFLDataFormat*) malloc (framesPerBufferAlsa * sizeof (SFLDataFormat));
rsmpl_out = (SFLDataFormat*) malloc (playbackAvailBytes*2);
// Do sample rate conversion
int nb_sample_down = toGet / sizeof (SFLDataFormat);
......@@ -967,12 +990,12 @@ void AlsaLayer::audioCallback(void)
} else {
if ( (tone == 0) && (file_tone == 0)) {
if (!tone && !file_tone) {
SFLDataFormat* zeros = (SFLDataFormat*) malloc (framesPerBufferAlsa * sizeof (SFLDataFormat));
SFLDataFormat *zeros = (SFLDataFormat*)malloc(playbackAvailBytes);
bzero (zeros, framesPerBufferAlsa * sizeof (SFLDataFormat));
write (zeros, framesPerBufferAlsa * sizeof (SFLDataFormat), _PlaybackHandle);
bzero (zeros, playbackAvailBytes);
write (zeros, playbackAvailBytes, _PlaybackHandle);
free (zeros);
}
......@@ -987,26 +1010,28 @@ void AlsaLayer::audioCallback(void)
}
// Playback ringtone
file_tone = _manager->getTelephoneFile();
if (file_tone && _RingtoneHandle) {
toGet = framesPerBufferAlsa;
maxBytes = toGet * sizeof (SFLDataFormat);
int ringtoneAvailSmpl = snd_pcm_avail_update(_RingtoneHandle);
int ringtoneAvailBytes = ringtoneAvailSmpl*sizeof(SFLDataFormat);
if (file_tone != NULL) {
// _debug("RINGTONE: %d", ringtoneAvailSmpl);
out = (SFLDataFormat*) malloc (maxBytes * sizeof (SFLDataFormat));
file_tone->getNext (out, toGet, spkrVolume);
write (out, maxBytes, _RingtoneHandle);
out = (SFLDataFormat *) malloc(ringtoneAvailBytes);
file_tone->getNext (out, ringtoneAvailSmpl, spkrVolume);
write (out, ringtoneAvailBytes, _RingtoneHandle);
free (out);
out = NULL;
} else {
} else if (_RingtoneHandle) {
int ringtoneAvailSmpl = snd_pcm_avail_update(_RingtoneHandle);
int ringtoneAvailBytes = ringtoneAvailSmpl*sizeof(SFLDataFormat);
out = (SFLDataFormat*) malloc ( maxBytes * sizeof (SFLDataFormat));
memset(out, 0, maxBytes * sizeof (SFLDataFormat));
write(out, maxBytes, _RingtoneHandle);
out = (SFLDataFormat *) malloc(ringtoneAvailBytes);
memset(out, 0, ringtoneAvailBytes);
write(out, ringtoneAvailBytes, _RingtoneHandle);
free(out);
out = NULL;
......
/*
* Copyright (C) 2007 - 2008 Savoir-Faire Linux inc.
* Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com>
* Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -214,8 +215,6 @@ class AlsaLayer : public AudioLayer {
* @return int The number of frames actually read
*/
int read( void* buffer, int toCopy);
/**
* Recover from XRUN state for capture
......@@ -227,8 +226,8 @@ class AlsaLayer : public AudioLayer {
* Recover from XRUN state for playback
* ALSA Library API
*/
void handle_xrun_playback( void );
void handle_xrun_playback( snd_pcm_t *handle );
void* adjustVolume( void* buffer , int len, int stream );
/**
......@@ -262,7 +261,7 @@ class AlsaLayer : public AudioLayer {
/** Vector to manage all soundcard index - description association of the system */
std::vector<HwIDPair> IDSoundCards;
bool _is_prepared_playback;
bool _is_prepared_playback;
bool _is_prepared_capture;
bool _is_running_playback;
bool _is_running_capture;
......
......@@ -228,7 +228,7 @@ AudioStream::createStream (pa_context* c, std::string *deviceName)
attributes->minreq = (uint32_t) -1;
pa_threaded_mainloop_lock(_mainloop);
pa_stream_connect_playback(s, NULL, attributes, (pa_stream_flags_t) (PA_STREAM_NOFLAGS), NULL, NULL);
pa_stream_connect_playback(s, NULL, attributes, (pa_stream_flags_t) (PA_STREAM_ADJUST_LATENCY|PA_STREAM_AUTO_TIMING_UPDATE), NULL, NULL);
pa_threaded_mainloop_unlock(_mainloop);
} else if (_streamType == UPLOAD_STREAM) {
......
......@@ -770,7 +770,6 @@ void PulseLayer::writeToSpeaker (void)
} else {
AudioLoop* tone = _manager->getTelephoneTone();
AudioLoop* file_tone = _manager->getTelephoneFile();
// flush remaining samples in _urgentRingBuffer
flushUrgent();
......@@ -787,22 +786,6 @@ void PulseLayer::writeToSpeaker (void)
pa_xfree (out);
}
//}
// else if (file_tone != 0) {
/*
if (playback->getStreamState() == PA_STREAM_READY) {
out = (SFLDataFormat*) pa_xmalloc (writeableSize);
int copied = file_tone->getNext (out, writeableSize / sizeof (SFLDataFormat), 100);
pa_stream_write (playback->pulseStream(), out, copied * sizeof (SFLDataFormat), NULL, 0, PA_SEEK_RELATIVE);
pa_xfree (out);
}
*/
} else {
......@@ -876,7 +859,7 @@ void PulseLayer::writeToSpeaker (void)
} else {
if ( (tone == 0) && (file_tone == 0)) {
if (tone == 0) {
SFLDataFormat* zeros = (SFLDataFormat*) pa_xmalloc (writeableSize);
......@@ -977,27 +960,29 @@ void PulseLayer::ringtoneToSpeaker(void)
int writableSize = pa_stream_writable_size(ringtone->pulseStream());
// _debug("writable size: %d", writableSize);
_debug("writable size: %d", writableSize);
if (file_tone) {
if(ringtone->getStreamState() == PA_STREAM_READY) {
out = (SFLDataFormat*)pa_xmalloc(writableSize);
out = (SFLDataFormat *)pa_xmalloc(writableSize);
int copied = file_tone->getNext(out, writableSize/sizeof(SFLDataFormat), 100);
pa_stream_write(ringtone->pulseStream(), out, copied*sizeof(SFLDataFormat), NULL, 0, PA_SEEK_RELATIVE);
pa_xfree(out);
}
}
else {
out = (SFLDataFormat*)pa_xmalloc(writableSize);
memset(out, 0, writableSize);
pa_stream_write(ringtone->pulseStream(), out, writableSize, NULL, 0, PA_SEEK_RELATIVE);
if(ringtone->getStreamState() == PA_STREAM_READY) {
out = (SFLDataFormat*)pa_xmalloc(writableSize);
memset(out, 0, writableSize);
pa_stream_write(ringtone->pulseStream(), out, writableSize, NULL, 0, PA_SEEK_RELATIVE);
pa_xfree(out);
pa_xfree(out);
}
}
......
......@@ -466,17 +466,7 @@
<!-- Audio devices methods -->
<method name="getInputAudioPluginList" tp:name-for-bindings="getInputAudioPluginList">
<tp:docstring>
</tp:docstring>
<annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="VectorString"/>
<arg type="as" name="list" direction="out">
<tp:docstring>
</tp:docstring>
</arg>
</method>
<method name="getOutputAudioPluginList" tp:name-for-bindings="getOutputAudioPluginList">
<method name="getAudioPluginList" tp:name-for-bindings="getAudioPluginList">
<tp:docstring>
</tp:docstring>
<annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="VectorString"/>
......
......@@ -505,28 +505,13 @@ void ConfigurationManager::setActiveCodecList(
}
// Audio devices related methods
std::vector<std::string> ConfigurationManager::getInputAudioPluginList() {
_debug("ConfigurationManager: Active codec list received");
std::vector<std::string> v;
v.push_back("default");
v.push_back("surround40");
v.push_back("plug:hw");
return v;
}
std::vector<std::string> ConfigurationManager::getOutputAudioPluginList() {
std::vector<std::string> ConfigurationManager::getAudioPluginList() {