Commit 16310f72 authored by Emmanuel Milou's avatar Emmanuel Milou

Merge branch 'master' of...

Merge branch 'master' of git+ssh://repos-sflphone-git@git.sflphone.org/var/repos/sflphone/git/sflphone
parents e69713b2 608ed45f
......@@ -99,8 +99,11 @@
<application>SFLphone</application> is a free software and is distributed under the GNU General Public License version 3. It is developed by Savoir-Faire Linux, a Canadian Linux consulting company, in partnership with the global community.
</para>
<para>
Among the many features we developed for you, we could highlight the high definition sound (wide-band audio codecs - speex, G722, Celt), audio recording, voicemail notification and call history.
More than a simple softphone, <application>SFLphone</application> supports advanced enterprise-class call features: unlimited number of calls, call transfer and on/off hold option.
Among the many features we developed for you, we could
highlight the high definition sound (wide-band audio
codecs - speex, G722, Celt), multiple conference call,
audio recording, voicemail notification, and call history.
More than a simple softphone, <application>SFLphone</application> supports advanced enterprise-class call features: unlimited number of calls, call transfer, and on/off hold option.
</para>
<para>
This release also provides advanced security features (secure RTP and TLS).
......@@ -137,7 +140,8 @@
<sect1 id="accounts">
<title>Managing your accounts</title>
<para>
<application>SFLphone</application> supports both IAX2 and SIP accounts.
<application>SFLphone</application> supports both IAX2
and SIP accounts.
</para>
<sect2 id="accounts_basic">
......@@ -507,36 +511,34 @@
</sect2>
<sect2 id="conferencecall" label="Conference calls">
<para>SFLphone now supports conference calling
integrating server like features in a simple
GUI.</para>
<para>SFLphone now supports conference call hosting
integrating server like features in a simple GUI.
</para>
<para>
<itemizedlist>
<listitem>
<guilabel>Create a conference</guilabel>
<para>To create a conference, drag and drop one call
<para>To host a conference, simply drag and drop one call
on another. Additional participants are
added the same way, dragging a call on the
conference icon. SFLphone automatically
includes into the newly created conference.
conference icon.
</para>
</listitem>
<listitem>
<guilabel>Leave a conference</guilabel>
<para>
The Main Participant may leave at any time to
answer any other incoming communication or initiate
new ones. The conference is not interupted if Main
Participant left it. Double clicking the conference
let the Main Participant reintroduce
the conference.
SFLphone conference model let you leave a conference that
you are currently hosting to answer any other incoming
communication or even initiate new ones. The conference is
not interupted Double clicking the conference icon
let you reintroduce the conference.
</para>
</listitem>
<listitem>
<guilabel>Multiple conference</guilabel>
<para>
SFLphone supports multiple conferences running
simultaneously. Conferences may be joined the same way
simultaneously. Two conferences can be joined the same way
they are created, dragging one on the
other.
</para>
......@@ -582,33 +584,39 @@
<para>
<itemizedlist>
<listitem>
<guilabel>PCMU</guilabel>
<guilabel>PCMU/PCMA</guilabel>
<para>
ITU-T telefony standard PCM formats, 8kHz, 64
kbit/s, using logarithmic byte compression algorithm.
</para>
</listitem>
<listitem>
<guilabel>PCMA</guilabel>
<para>
</para>
</listitem>
<listitem>
<guilabel>GSM</guilabel>
<para>
Global System for Mobile communications (GSM)
narrowband 8kHz standard based on linear prediction encoding.
</para>
</listitem>
<listitem>
<guilabel>G722</guilabel>
<para>
ITU-T standard wideband 16kHz standard based on linear prediction.
</para>
</listitem>
<listitem>
<guilabel>SPEEX</guilabel>
<para>
High quality voice encoding/decoding available
in narrowband 8Khz, wideband 16khz (HD Voice),
and ultra-wideband 32 kHz.
Integrate additional features such as Variable Bit
Rate (VBR) and noise reduction.
</para>
</listitem>
<listitem>
<guilabel>CELT</guilabel>
<para>
</para>
</listitem>
</itemizedlist>
......
......@@ -184,27 +184,27 @@ AudioStream::createStream (pa_context* c)
// parameters are defined as number of bytes
// 2048 bytes (1024 int16) is 20 ms at 44100 Hz
if (_streamType == PLAYBACK_STREAM) {
attributes->maxlength = 16000;
attributes->tlength = 8192;
attributes->maxlength = 88200;
attributes->tlength = 22050;
attributes->prebuf = 4096; // Pulseaudio will not start if prebuffering is not reached
attributes->minreq = 2048; // The server side playback framesize
attributes->fragsize = 4096; // Fragment size at wich we receive an interupt
pa_stream_connect_playback( s , NULL , attributes, PA_STREAM_INTERPOLATE_TIMING, &_volume, NULL);
attributes->minreq = 2048; // The server side playback framesize
attributes->fragsize = 11025; // Fragment size at wich we receive an interupt
pa_stream_connect_playback( s , NULL , attributes, PA_STREAM_NOFLAGS, &_volume, NULL);
// pa_stream_connect_playback (s , NULL , attributes, PA_STREAM_START_CORKED, &_volume, NULL);
} else if (_streamType == CAPTURE_STREAM) {
// attributes->maxlength = 66500;
// attributes->fragsize = (uint32_t)-1;
attributes->maxlength = 32000;
attributes->tlength = (uint32_t)-1;
attributes->prebuf = (uint32_t)-1;
attributes->minreq = (uint32_t)-1;
attributes->fragsize = 4096;
attributes->maxlength = 88200;
attributes->tlength = 22050;
attributes->prebuf = 4096;
attributes->minreq = 2048;
attributes->fragsize = 11025;
// pa_stream_connect_record (s , NULL , attributes , PA_STREAM_START_CORKED);
// pa_stream_connect_record( s , NULL , attributes , PA_STREAM_INTERPOLATE_TIMING );
pa_stream_connect_record( s, NULL, NULL, PA_STREAM_INTERPOLATE_TIMING );
pa_stream_connect_record( s, NULL, NULL, PA_STREAM_NOFLAGS);
} else if (_streamType == UPLOAD_STREAM) {
pa_stream_connect_upload (s , 1024);
} else {
......
......@@ -30,6 +30,7 @@ static void playback_callback (pa_stream* s, size_t bytes, void* userdata)
assert (s && bytes);
assert (bytes > 0);
static_cast<PulseLayer*> (userdata)->processPlaybackData();
// static_cast<PulseLayer*> (userdata)->processData();
}
static void capture_callback (pa_stream* s, size_t bytes, void* userdata)
......@@ -39,6 +40,7 @@ static void capture_callback (pa_stream* s, size_t bytes, void* userdata)
assert(s && bytes);
assert(bytes > 0);
static_cast<PulseLayer*> (userdata)->processCaptureData();
// static_cast<PulseLayer*> (userdata)->processData();
}
......@@ -357,12 +359,15 @@ void PulseLayer::startStream (void)
// Create Streams
connectPulseAudioServer();
_urgentRingBuffer.flushAll();
_mainBuffer.flushAllBuffers();
// _urgentRingBuffer.flushAll();
// _mainBuffer.flushAllBuffers();
is_started = true;
}
_urgentRingBuffer.flushAll();
_mainBuffer.flushAllBuffers();
}
void
......@@ -451,6 +456,30 @@ void PulseLayer::processCaptureData(void)
}
void PulseLayer::processData(void)
{
// Handle the data for the speakers
if ( playback &&(playback->pulseStream()) && (pa_stream_get_state (playback->pulseStream()) == PA_STREAM_READY)) {
// _debug("PulseLayer::processPlaybackData()\n");
// If the playback buffer is full, we don't overflow it; wait for it to have free space
if (pa_stream_writable_size (playback->pulseStream()) == 0)
return;
writeToSpeaker();
}
// Handle the mic
// We check if the stream is ready
if ( record &&(record->pulseStream()) && (pa_stream_get_state (record->pulseStream()) == PA_STREAM_READY))
readFromMic();
}
void PulseLayer::writeToSpeaker (void)
{
/** Bytes available in the urgent ringbuffer ( reserved for DTMF ) */
......@@ -471,9 +500,9 @@ void PulseLayer::writeToSpeaker (void)
urgentAvailBytes = _urgentRingBuffer.AvailForGet();
if (urgentAvailBytes > 0) {
if (urgentAvailBytes > (framesPerBuffer*sizeof(SFLDataFormat))) {
// _debug("urgentAvailBytes: %i\n", urgentAvailBytes);
_debug("urgentAvailBytes: %i\n", urgentAvailBytes);
toGet = (urgentAvailBytes < (int) (framesPerBuffer * sizeof (SFLDataFormat))) ? urgentAvailBytes : framesPerBuffer * sizeof (SFLDataFormat);
out = (SFLDataFormat*) pa_xmalloc (toGet * sizeof (SFLDataFormat));
......@@ -490,6 +519,8 @@ void PulseLayer::writeToSpeaker (void)
AudioLoop* tone = _manager->getTelephoneTone();
AudioLoop* file_tone = _manager->getTelephoneFile();
_urgentRingBuffer.flushAll();
if (tone != 0) {
if (playback->getStreamState() == PA_STREAM_READY)
......@@ -577,12 +608,14 @@ void PulseLayer::writeToSpeaker (void)
if((tone == 0) && (file_tone == 0)) {
// _debug("maxNbBytesToGet: %i\n", maxNbBytesToGet);
SFLDataFormat* zeros = (SFLDataFormat*)pa_xmalloc (framesPerBuffer*sizeof(SFLDataFormat));
bzero (zeros, framesPerBuffer*sizeof(SFLDataFormat));
pa_stream_write(playback->pulseStream(), zeros, framesPerBuffer*sizeof(SFLDataFormat), NULL, 0, PA_SEEK_RELATIVE);
pa_xfree (zeros);
}
}
......@@ -603,7 +636,7 @@ void PulseLayer::readFromMic (void)
size_t r;
if (pa_stream_peek (record->pulseStream() , (const void**) &data , &r) < 0 || !data) {
//_debug("pa_stream_peek() failed: %s\n" , pa_strerror( pa_context_errno( context) ));
_debug("pa_stream_peek() failed: %s\n" , pa_strerror( pa_context_errno( context) ));
}
if (data != 0) {
......
......@@ -133,6 +133,8 @@ class PulseLayer : public AudioLayer {
void processPlaybackData( void );
void processCaptureData( void );
void processData(void);
private:
// Copy Constructor
......
......@@ -1651,6 +1651,8 @@ ManagerImpl::playDtmf (char code, bool isTalking)
AudioLayer *audiolayer;
SFLDataFormat *buf;
_debug("ManagerImpl::playDtmf\n");
stopTone (false);
bool hasToPlayTone = getConfigBool (SIGNALISATION, PLAY_DTMF);
......@@ -1689,6 +1691,9 @@ ManagerImpl::playDtmf (char code, bool isTalking)
// ms/s
size = (int) ((pulselen * (float) audiolayer->getSampleRate()) / 1000);
_debug("DTMF pulselen: %i\n", pulselen);
_debug("DTMF size: %i\n", size);
// this buffer is for mono
// TODO <-- this should be global and hide if same size
buf = new SFLDataFormat[size];
......@@ -2023,6 +2028,8 @@ bool ManagerImpl::playATone (Tone::TONEID toneId)
AudioLayer *audiolayer;
unsigned int nbSamples;
_debug("ManagerImpl::playATone\n");
hasToPlayTone = getConfigBool (SIGNALISATION, PLAY_TONES);
if (!hasToPlayTone)
......@@ -2213,6 +2220,8 @@ void ManagerImpl::notificationIncomingCall (void)
audiolayer = getAudioDriver();
_debug("ManagerImpl::notificationIncomingCall\n");
if (audiolayer != 0) {
samplerate = audiolayer->getSampleRate();
frequency << "440/" << FRAME_PER_BUFFER;
......
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