Commit 1a2dd7df authored by yanmorin's avatar yanmorin

Adding switch echo echo (for testing only...)

Adding magnetism to dtmf window
Adding sample rate combobox
parent 97e587ad
2006-08-31 Yan Morin
* Add samplerate combobox if sample rate is compiled
* Fix Bug when moving sflphone and clicking inside the lcd
* Adding magnetism to Dtmf window
* Moving Dtmf window to the left of sflphone
2006-08-30 Yan Morin
* Set libsamplerate as a dependency
......
For project core:
----------------
Management Config like about:config in Mozilla
Improvement of STUN
Add IAX support
Management of account (add, remove, ...)
Management of exceptions
Remove all warnings in compilation
Improvement of STUN (done?)
Better handling for an reINVITE request. (done?)
Mono channel, float for portaudio
Management of account (add, remove, ...) (done?)
For project dependencies:
------------------------
......@@ -16,9 +16,7 @@ Improve the autotools scripts of PortAudioCpp
For sflphone-qt:
---------------
Add samplerate combobox if sample rate is compiled
Save account status if modified in configuration
Bug when moving sflphone and clicking inside the lcd
From FIXME:
......
......@@ -100,9 +100,7 @@ AudioFile::loadFile(const std::string& filename, unsigned int sampleRate=8000)
_size = nbSampling;
_buffer = new SFLDataFormat[_size];
// src to dest
for(unsigned int i=0; i<nbSampling; i++) {
_buffer[i] = SFLConvertInt16(monoBuffer[i]);
}
src_short_to_float_array(monoBuffer, _buffer, nbSampling);
} else {
// case 2: we need to convert it and split it
// convert here
......
......@@ -44,6 +44,7 @@ AudioLayer::AudioLayer(ManagerImpl* manager)
_inChannel = 1; // don't put in stereo
_outChannel = 1; // don't put in stereo
_echoTesting = false;
try {
portaudio::AutoSystem autoSys;
......@@ -361,6 +362,12 @@ AudioLayer::isStreamStopped (void)
return false;
}
void
AudioLayer::toggleEchoTesting() {
ost::MutexLock guard(_mutex);
_echoTesting = (_echoTesting == true) ? false : true;
}
int
AudioLayer::audioCallback (const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
......@@ -372,6 +379,12 @@ AudioLayer::audioCallback (const void *inputBuffer, void *outputBuffer,
SFLDataFormat *in = (SFLDataFormat *) inputBuffer;
SFLDataFormat *out = (SFLDataFormat *) outputBuffer;
if (_echoTesting) {
memcpy(out, in, framesPerBuffer*sizeof(SFLDataFormat));
return paContinue;
}
int toGet;
int toPut;
int urgentAvail; // number of data right and data left
......
......@@ -78,6 +78,11 @@ public:
enum IODEVICE {InputDevice=0x01, OutputDevice=0x02 };
/**
* Toggle echo testing on/off
*/
void toggleEchoTesting();
private:
void closeStream (void);
RingBuffer _urgentRingBuffer;
......@@ -104,6 +109,12 @@ private:
*/
unsigned int _outChannel; // speaker
/**
* Echo testing or not
*/
bool _echoTesting;
std::string _errorMessage;
ost::Mutex _mutex;
......
......@@ -135,7 +135,7 @@ GuiFramework::playTone ()
bool
GuiFramework::stopTone ()
{
Manager::instance().stopTone();
Manager::instance().stopTone(true);
return true;
}
......
......@@ -241,3 +241,27 @@ ConfigurationManagerImpl::reloadSoundDriver() {
this, SIGNAL(audioDevicesOutUpdated()));
}
const QString
ConfigurationManagerImpl::getAudioDevicesInRate(int index) {
std::list< AudioDevice >::iterator pos;
int i=0;
for (pos = mAudioDevicesIn.begin(); pos!=mAudioDevicesIn.end(); pos++, i++) {
if (index == i) {
return pos->defaultRate;
}
}
return QString("");
}
const QString
ConfigurationManagerImpl::getAudioDevicesOutRate(int index) {
std::list< AudioDevice >::iterator pos;
int i=0;
for (pos = mAudioDevicesOut.begin(); pos!=mAudioDevicesOut.end(); pos++, i++) {
if (index == i) {
return pos->defaultRate;
}
}
return QString("");
}
......@@ -141,6 +141,11 @@ public:
{return mAudioDevicesIn;}
std::list< AudioDevice > getAudioDevicesOut()
{return mAudioDevicesOut;}
/** Get Audio Device In pointer, or null if not found */
const QString getAudioDevicesInRate(int index);
/** Get Audio Device Out pointer, or null if not found */
const QString getAudioDevicesOutRate(int index);
std::list< Ringtone > getRingtones()
{return mRingtones;}
......
......@@ -780,6 +780,13 @@
<property name="name"><cstring>cboDriverChoiceIn</cstring></property>
</widget>
</widget>
<widget class="QVButtonGroup">
<property name="name"><cstring>DriverRate</cstring></property>
<property name="title"><string>Sample rate</string></property>
<widget class="QComboBox">
<property name="name"><cstring>cboDriverRate</cstring></property>
</widget>
</widget>
<widget class="QLayoutWidget">
<property name="name"><cstring>layoutforsounddriver</cstring></property>
......@@ -1532,6 +1539,7 @@ Montreal, Quebec H2T 1S6, Canada&lt;/p&gt;</string>
<tabstop>Tab_Audio</tabstop>
<tabstop>cboDriverChoiceOut</tabstop>
<tabstop>cboDriverChoiceIn</tabstop>
<tabstop>cboDriverRate</tabstop>
<tabstop>buttonTestSoundDriver</tabstop>
<tabstop>buttonReloadSoundDriver</tabstop>
<tabstop>codec1</tabstop>
......@@ -1575,6 +1583,7 @@ Montreal, Quebec H2T 1S6, Canada&lt;/p&gt;</string>
</functions>
<variables>
<variable access="private">int lastSIPAccount;</variable>
<variable access="private">int _cutStringCombo;</variable>
</variables>
......
......@@ -51,12 +51,13 @@
void ConfigurationPanel::init()
{
_cutStringCombo = 30;
DebugOutput::instance() << "ConfigurationPanel::init()\n";
lblError->hide();
Tab_Signalisations->show();
Tab_Audio->hide();
Tab_Preferences->hide();
Tab_About->hide();
lblError->hide();
Tab_Signalisations->show();
Tab_Audio->hide();
Tab_Preferences->hide();
Tab_About->hide();
/*
// For reading settings at application startup
......@@ -116,17 +117,11 @@ void
ConfigurationPanel::generate()
{
// For audio tab
codec1->setCurrentText(ConfigurationManager::instance()
.get(AUDIO_SECTION, AUDIO_CODEC1));
codec2->setCurrentText(ConfigurationManager::instance()
.get(AUDIO_SECTION, AUDIO_CODEC2));
codec3->setCurrentText(ConfigurationManager::instance()
.get(AUDIO_SECTION, AUDIO_CODEC3));
codec1->setCurrentText(ConfigurationManager::instance().get(AUDIO_SECTION, AUDIO_CODEC1));
codec2->setCurrentText(ConfigurationManager::instance().get(AUDIO_SECTION, AUDIO_CODEC2));
codec3->setCurrentText(ConfigurationManager::instance().get(AUDIO_SECTION, AUDIO_CODEC3));
ringsChoice->setCurrentText(ConfigurationManager::instance().get(AUDIO_SECTION,
AUDIO_RINGTONE));
ringsChoice->setCurrentText(ConfigurationManager::instance().get(AUDIO_SECTION, AUDIO_RINGTONE));
// For signalisations tab
......@@ -150,19 +145,24 @@ ConfigurationPanel::generate()
}
loadSIPAccount(0);
sendDTMFas->setCurrentItem(ConfigurationManager::instance()
.get(SIGNALISATION_SECTION,
SIGNALISATION_SEND_DTMF_AS).toUInt());
playTones->setChecked(ConfigurationManager::instance()
.get(SIGNALISATION_SECTION,
SIGNALISATION_PLAY_TONES).toUInt());
pulseLength->setValue(ConfigurationManager::instance()
.get(SIGNALISATION_SECTION,
SIGNALISATION_PULSE_LENGTH).toUInt());
sendDTMFas->setCurrentItem(ConfigurationManager::instance().get(SIGNALISATION_SECTION,
SIGNALISATION_SEND_DTMF_AS).toUInt());
playTones->setChecked(ConfigurationManager::instance().get(SIGNALISATION_SECTION,
SIGNALISATION_PLAY_TONES).toUInt());
pulseLength->setValue(ConfigurationManager::instance().get(SIGNALISATION_SECTION,
SIGNALISATION_PULSE_LENGTH).toUInt());
cboDriverChoiceOut->setCurrentItem(ConfigurationManager::instance().get(AUDIO_SECTION, AUDIO_DEFAULT_DEVICEOUT).toUInt());
cboDriverChoiceIn->setCurrentItem(ConfigurationManager::instance().get(AUDIO_SECTION, AUDIO_DEFAULT_DEVICEIN).toUInt());
// fill cboDriverRate here
int nbRate = 5;
int allowedRate[5] = {8000,16000,32000,44100,48000};
cboDriverRate->clear();
for(int iRate = 0; iRate < nbRate; iRate++) {
cboDriverRate->insertItem(QString::number(allowedRate[iRate]));
}
cboDriverRate->setCurrentText(ConfigurationManager::instance().get(AUDIO_SECTION, AUDIO_SAMPLERATE));
//preference tab
updateSkins();
......@@ -312,10 +312,10 @@ void ConfigurationPanel::updateAudioDevicesIn()
QString hostApiName = pos->hostApiName;
QString deviceName = pos->deviceName;
QString name = hostApiName + QObject::tr(" (device #%1)").arg(pos->index);
if (name.length() > 50) {
name = name.left(50) + "...";
if (hostApiName.length() > _cutStringCombo) {
hostApiName = hostApiName.left(_cutStringCombo) + "...";
}
QString name = hostApiName + QObject::tr(" (device #%1-%2Hz)").arg(pos->index).arg(pos->defaultRate);
cbo->insertItem(name);
}
}
......@@ -336,10 +336,11 @@ void ConfigurationPanel::updateAudioDevices()
QString hostApiName = pos->hostApiName;
QString deviceName = pos->deviceName;
QString name = hostApiName + QObject::tr(" (device #%1)").arg(pos->index);
if (name.length() > 50) {
name = name.left(50) + "...";
if (hostApiName.length() > _cutStringCombo) {
hostApiName = hostApiName.left(_cutStringCombo) + "...";
}
DebugOutput::instance() << hostApiName << pos->defaultRate;
QString name = hostApiName + QObject::tr(" (device #%1-%2Hz)").arg(pos->index).arg(pos->defaultRate);
cbo->insertItem(name);
}
}
......@@ -384,10 +385,14 @@ ConfigurationPanel::slotTestSoundDriver()
if (cboDriverChoiceIn->currentText() != NULL) {
ConfigurationManager::instance().set(AUDIO_SECTION, AUDIO_DEFAULT_DEVICEIN, QString::number(cboDriverChoiceIn->currentItem()));
}
if (cboDriverRate->currentText() != NULL) {
ConfigurationManager::instance().set(AUDIO_SECTION, AUDIO_SAMPLERATE, cboDriverRate->currentText());
}
// save driver on portaudio
ConfigurationManager::instance().save(AUDIO_SECTION, AUDIO_DEFAULT_DEVICEOUT);
ConfigurationManager::instance().save(AUDIO_SECTION, AUDIO_DEFAULT_DEVICEIN);
ConfigurationManager::instance().save(AUDIO_SECTION, AUDIO_SAMPLERATE);
emit soundDriverChanged();
}
......
......@@ -69,3 +69,5 @@ ConfigurationPanelImpl::generate()
show();
}
......@@ -54,12 +54,12 @@
#define DTMF_CLOSE_RELEASED_IMAGE QString("dtmf_close_off.png")
#define DTMF_CLOSE_PRESSED_IMAGE QString("dtmf_close_on.png")
NumericKeypad::NumericKeypad()
NumericKeypad::NumericKeypad(QWidget* parent = 0, bool showAtStart=false)
//: TransparentWidget(PIXMAP_KEYPAD_IMAGE, NULL)
: QDialog(NULL,
: QDialog(parent,
"DTMF Keypad",
false,
Qt::WStyle_Customize)
Qt::WStyle_Customize), mWinRef(0)
{
TransparentWidget::setPaletteBackgroundPixmap(this, PIXMAP_KEYPAD_IMAGE);
resize(TransparentWidget::retreive(PIXMAP_KEYPAD_IMAGE).size());
......@@ -163,6 +163,13 @@ NumericKeypad::NumericKeypad()
this, SLOT(hide()));
connect(mKeyClose, SIGNAL(clicked()),
this, SLOT(slotHidden()));
mAlreadySet = false;
if (showAtStart) {
mAlreadySet = true;
show();
emit isShown(true);
}
}
NumericKeypad::~NumericKeypad()
......@@ -212,7 +219,36 @@ NumericKeypad::mouseMoveEvent(QMouseEvent *e)
// Note that moving the windows is very slow
// 'cause it redraw the screen each time.
// Usually it doesn't. We could do it by a timer.
move(e->globalPos() - mLastPos);
QPoint pt = e->globalPos() - mLastPos;
if (mWinRef) {
int range = 5;
int px0 = pt.x();
int py0 = pt.y();
int px1 = px0 + width();
int py1 = py0 + height();
// DebugOutput::instance() << "Pt (x0,y0): " << px0 << " " << py0 << "\n";
// DebugOutput::instance() << "Pt (x1,y1): " << px1 << " " << py1 << "\n";
int wx0 = mWinRef->pos().x();
int wy0 = mWinRef->pos().y();
int wx1 = wx0 + mWinRef->width();
int wy1 = wy0 + mWinRef->height();
// DebugOutput::instance() << "mWinRef (x0,y0): " << wx0 << " " << wy0 << "\n";
// DebugOutput::instance() << "mWinRef (x1,y1): " << wx1 << " " << wy1 << "\n";
// x and y
if (abs(px0-wx1) <= range) { pt.setX(wx1); }
else if (abs(px1-wx0) <= range) { pt.setX(wx0-width()); }
// top and down
if (abs(py0-wy0) <= range) { pt.setY(wy0); }
// the numeric under the telephone
else if (abs(py0-wy1) <= range) { pt.setY(wy1); }
// the numeric over the telephone
else if (abs(py1-wy0) <= range) { pt.setY(wy0-height()); }
}
move(pt);
}
void
......@@ -270,3 +306,11 @@ NumericKeypad::slotHidden()
{
emit isShown(false);
}
void
NumericKeypad::setDefaultPosition(const QPoint& point) {
if (mWinRef && !mAlreadySet) {
move(point);
mAlreadySet = true;
}
}
......@@ -33,7 +33,7 @@ class NumericKeypad : public QDialog
Q_OBJECT
public:
// Default Constructor and destructor
NumericKeypad();
NumericKeypad(QWidget* parent/*=0*/, bool showAtStart/*=false*/);
~NumericKeypad();
JPushButton *mKey0;
......@@ -50,6 +50,10 @@ public:
JPushButton *mKeyHash;
JPushButton *mKeyClose;
/** Set default position of the window */
void setDefaultPosition(const QPoint&);
void setWindowReference(QWidget* widget) { mWinRef = widget; }
public slots:
void mousePressEvent(QMouseEvent *e);
void mouseMoveEvent(QMouseEvent *e);
......@@ -77,6 +81,9 @@ signals:
private:
QPoint mLastPos;
std::map< Qt::Key, JPushButton * > mKeys;
/** Window reference when moving the window (magnetic style) */
QWidget* mWinRef;
bool mAlreadySet; // already set the default position or not?
};
#endif // __NUMERIC_KEYPAD_H__
......@@ -78,8 +78,6 @@ SFLPhoneApp::SFLPhoneApp(int argc, char **argv)
Requester::instance().registerObject< Request >(QString("setspkrvolume"));
Requester::instance().registerObject< Request >(QString("setmicvolume"));
Requester::instance().registerObject< Request >(QString("mute"));
mKeypad = new NumericKeypad();
}
SFLPhoneApp::~SFLPhoneApp()
......@@ -148,12 +146,6 @@ SFLPhoneApp::initConnections(SFLPhoneWindow *w)
&PhoneLineManager::instance(), SLOT(call()));
QObject::connect(w->mMute, SIGNAL(toggled(bool)),
&PhoneLineManager::instance(), SLOT(mute(bool)));
QObject::connect(w->mDtmf, SIGNAL(toggled(bool)),
mKeypad, SLOT(setShown(bool)));
//QObject::connect(mKeypad, SIGNAL(hidden()),
// w->mDtmf, SLOT(release()));
QObject::connect(mKeypad, SIGNAL(isShown(bool)),
w->mDtmf, SLOT(setOn(bool)));
QObject::connect(w->mSetup, SIGNAL(clicked()),
&PhoneLineManager::instance(), SLOT(setup()));
QObject::connect(w->mHangup, SIGNAL(clicked()),
......@@ -175,7 +167,7 @@ SFLPhoneApp::initConnections(SFLPhoneWindow *w)
// Keypad connections
QObject::connect(mKeypad, SIGNAL(keyPressed(Qt::Key)),
QObject::connect(w->mKeypad, SIGNAL(keyPressed(Qt::Key)),
&PhoneLineManager::instance(), SLOT(sendKey(Qt::Key)));
// LCD Connections.
......
......@@ -67,7 +67,6 @@ signals:
private:
Launcher *mLauncher;
NumericKeypad *mKeypad;
Session *mSession;
};
......
......@@ -40,6 +40,7 @@
#include "PhoneLineButton.hpp"
#include "SFLLcd.hpp"
#include "VolumeControl.hpp"
#include "NumericKeypad.hpp"
#define LOGO_IMAGE "logo_ico.png"
#define BACKGROUND_IMAGE "main.png"
......@@ -58,6 +59,10 @@ SFLPhoneWindow::SFLPhoneWindow()
{
mLastWindowPos = pos();
mSetupPanel = new ConfigurationPanel(this, "ConfigurationPanel");
mKeypad = new NumericKeypad(NULL, false);
mKeypad->setWindowReference(this);
connect(this, SIGNAL(ringtonesUpdated()), mSetupPanel, SLOT(updateRingtones()));
connect(this, SIGNAL(audioDevicesUpdated()), mSetupPanel, SLOT(updateAudioDevices()));
connect(this, SIGNAL(audioDevicesInUpdated()), mSetupPanel, SLOT(updateAudioDevicesIn()));
......@@ -119,6 +124,9 @@ SFLPhoneWindow::initGUIButtons()
mMute->setToggleButton(true);
mDtmf = new QPushButton(QObject::tr("DTMF"), this, "dtmf");
mDtmf->setToggleButton(true);
connect(mKeypad, SIGNAL(isShown(bool)), mDtmf, SLOT(setOn(bool)));
connect(mDtmf, SIGNAL(toggled(bool)), this, SLOT(toggleDtmf(bool)));
mSetup = new QPushButton(QObject::tr("Setup"), this, "setup");
mTransfer = new QPushButton(QObject::tr("Transfer"), this, "transfer");
mRedial = new QPushButton(QObject::tr("Redial"), this, "redial");
......@@ -258,3 +266,14 @@ SFLPhoneWindow::delayedPaint()
move(mLastWindowPos);
}
}
void
SFLPhoneWindow::toggleDtmf(bool toggle)
{
if (mKeypad) {
if (toggle) {
mKeypad->setDefaultPosition(QPoint(pos().x()+width(), pos().y()));
}
mKeypad->setShown(toggle);
}
}
......@@ -34,6 +34,7 @@ class JPushButton;
class PhoneLineButton;
class SFLLcd;
class VolumeControl;
class NumericKeypad;
class SFLPhoneWindow : public QMainWindow
{
......@@ -106,6 +107,11 @@ public slots:
void showSetup();
void hideSetup();
/**
* toggle the dtmf window
*/
void toggleDtmf(bool);
protected:
void keyPressEvent(QKeyEvent *e);
......@@ -135,5 +141,6 @@ private:
QPoint mLastWindowPos;
QTimer *mPaintTimer;
NumericKeypad *mKeypad;
ConfigurationPanel *mSetupPanel;
};
/**
/*
* Copyright (C) 2004-2005 Savoir-Faire Linux inc.
* Author: Jean-Philippe Barrette-LaPierre
* <jean-philippe.barrette-lapierre@savoirfairelinux.com>
......@@ -23,12 +23,13 @@
#define NB_PHONELINES 6
#define PROGNAME "SFLPhone"
#define VERSION "0.4.2"
#define VERSION "0.7.0"
#define AUDIO_SECTION "Audio"
#define AUDIO_DEFAULT_DEVICE "Drivers.driverName"
#define AUDIO_DEFAULT_DEVICEIN "Drivers.driverNameIn"
#define AUDIO_DEFAULT_DEVICEOUT "Drivers.driverNameOut"
#define AUDIO_SAMPLERATE "Drivers.sampleRate"
#define AUDIO_CODEC1 "Codecs.codec1"
#define AUDIO_CODEC2 "Codecs.codec2"
......
......@@ -117,7 +117,6 @@ ManagerImpl::init()
initAudioDriver();
selectAudioDriver();
initAudioCodec();
AudioLayer *audiolayer = getAudioDriver();
......@@ -215,7 +214,7 @@ ManagerImpl::outgoingCall(const std::string& accountid, const CallID& id, const
bool
ManagerImpl::answerCall(const CallID& id)
{
stopTone();
stopTone(false);
AccountID accountid = getAccountFromCall( id );
if (accountid == AccountNULL) {
......@@ -249,7 +248,7 @@ ManagerImpl::sendTextMessage(const AccountID& accountId, const std::string& to,
bool
ManagerImpl::hangupCall(const CallID& id)
{
stopTone();
stopTone(true);
AccountID accountid = getAccountFromCall( id );
if (accountid == AccountNULL) {
......@@ -268,7 +267,7 @@ ManagerImpl::hangupCall(const CallID& id)
bool
ManagerImpl::cancelCall (const CallID& id)
{
stopTone();
stopTone(true);
AccountID accountid = getAccountFromCall( id );
if (accountid == AccountNULL) {
_debug("! Manager Cancel Call: Call doesn't exists\n");
......@@ -288,7 +287,7 @@ ManagerImpl::cancelCall (const CallID& id)
bool
ManagerImpl::onHoldCall(const CallID& id)
{
stopTone();
stopTone(true);
AccountID accountid = getAccountFromCall( id );
if (accountid == AccountNULL) {
_debug("5 Manager On Hold Call: Account ID %s or callid %s desn't exists\n", accountid.c_str(), id.c_str());
......@@ -306,7 +305,7 @@ ManagerImpl::onHoldCall(const CallID& id)
bool
ManagerImpl::offHoldCall(const CallID& id)
{
stopTone();
stopTone(false);
AccountID accountid = getAccountFromCall( id );
if (accountid == AccountNULL) {
_debug("5 Manager OffHold Call: Call doesn't exists\n");
......@@ -329,7 +328,7 @@ ManagerImpl::offHoldCall(const CallID& id)
bool
ManagerImpl::transferCall(const CallID& id, const std::string& to)
{
stopTone();
stopTone(true);
AccountID accountid = getAccountFromCall( id );
if (accountid == AccountNULL) {
_debug("! Manager Transfer Call: Call doesn't exists\n");
......@@ -362,7 +361,7 @@ ManagerImpl::unmute() {
bool
ManagerImpl::refuseCall (const CallID& id)
{
stopTone();