Commit 704061b5 authored by llea's avatar llea

Fix timer call, dialtone, blocking bug.

parent f38af512
/**
* Copyright (C) 2004 Savoir-Faire Linux inc.
* Author: Laurielle Lea <laurielle.lea@savoirfairelinux.com>
*
* Portions Copyright (c) 2000 Billy Biggs <bbiggs@div8.net>
* Portions Copyright (c) 2004 Wirlab <kphone@wirlab.net>
*
* 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "audiobuffer.h"
#include "global.h"
#include <string.h>
AudioBuffer::AudioBuffer (void) {
data = new unsigned char[BUF_SIZE];
size = BUF_SIZE;
data = new short[SIZEBUF];
bzero(data, SIZEBUF);
size = SIZEBUF;
realsize = size;
}
AudioBuffer::~AudioBuffer (void)
{
delete[] data;
delete[] static_cast<short *>(data);
}
void AudioBuffer::resize (size_t newsize)
{
if (newsize > realsize) {
delete[] data;
data = new unsigned char[newsize];
delete[] static_cast<short *>(data);
data = new short[newsize];
size = newsize;
realsize = newsize;
} else {
size = newsize;
}
}
void
AudioBuffer::setData (short *buf) {
short *databuf = data;
for (int i = 0; i < (int)size; i++) {
databuf[i] = buf[i];
}
}
/**
* Copyright (C) 2004 Savoir-Faire Linux inc.
* Author: Laurielle Lea <laurielle.lea@savoirfairelinux.com>
*
* Portions Copyright (c) 2000 Billy Biggs <bbiggs@div8.net>
* Portions Copyright (c) 2004 Wirlab <kphone@wirlab.net>
*
* 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __AUDIOBUFFER_H__
#define __AUDIOBUFFER_H__
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#define BUF_SIZE 4096
/**
* Small class for passing around buffers of audio data.
......@@ -24,7 +45,7 @@ public:
/**
* Returns a pointer to the audio data.
*/
unsigned char *getData (void) {
void *getData (void) {
return data;
}
......@@ -41,8 +62,10 @@ public:
*/
void resize (size_t newsize);
void setData (short *buf);
void *data;
private:
unsigned char *data;
size_t size;
size_t realsize;
};
......
......@@ -25,6 +25,7 @@
AudioDrivers::AudioDrivers (void) {
this->devstate = AudioDrivers::DeviceClosed;
}
AudioDrivers::~AudioDrivers (void) {
......
......@@ -43,14 +43,15 @@ public:
virtual int resetDevice (void) = 0;
virtual int closeDevice (void) = 0;
virtual int writeBuffer (void *, int) = 0;
virtual int writeBuffer (void) = 0;
virtual int readBuffer (void *, int) = 0;
virtual void flushReadBuffer (void) = 0;
virtual int readBuffer (int) = 0;
virtual unsigned int readableBytes (void) = 0;
AudioBuffer audio_buf; // Buffer that the application fills
protected:
DeviceState devstate; // Current state
DeviceMode devmode; // Current mode
AudioBuffer audio_buf; // Buffer that the application fills
};
......
......@@ -81,7 +81,7 @@ AudioDriversOSS::initDevice (DeviceMode mode) {
// Open device in non-blocking mode
audio_fd = open (AUDIO_DEVICE, oflag | O_NONBLOCK );
if (audio_fd == -1) {
qWarning("ERROR: Open Failed");
printf ("ERROR: Open Failed\n");
return -1;
}
......@@ -92,7 +92,7 @@ AudioDriversOSS::initDevice (DeviceMode mode) {
// Fragments : No limit (0x7FFF),
int frag = ( ( 0x7FFF << 16 ) | 7 );
if (ioctl(audio_fd, SNDCTL_DSP_SETFRAGMENT, &frag)) {
qWarning("ERROR: SETFRAG %s", (QString(strerror(errno))).ascii());
printf ("ERROR: SETFRAG %s\n", strerror(errno));
return -1;
}
......@@ -101,34 +101,34 @@ AudioDriversOSS::initDevice (DeviceMode mode) {
format = AFMT_S16_LE;
if (ioctl(audio_fd, SNDCTL_DSP_SETFMT, &format) == -1) {
qWarning("ERROR: SETFMT %s", (QString(strerror(errno))).ascii());
printf("ERROR: SETFMT %s\n", strerror(errno));
return -1;
}
if (format != AFMT_S16_LE) {
qWarning("ERROR: Format not supported");
printf ("ERROR: Format not supported\n");
return -1;
}
// Setup number of channels
int channels = MONO;
if (ioctl(audio_fd, SNDCTL_DSP_CHANNELS, &channels) == -1) {
qWarning("ERROR: DSP_STEREO %s", (QString(strerror(errno))).ascii());
printf ("ERROR: DSP_STEREO %s\n", strerror(errno));
return false;
}
if (channels != MONO) {
qWarning("ERROR: Unsupported Number of Channels");
printf ("ERROR: Unsupported Number of Channels\n");
return false;
}
// Setup sampling rate
int rate = SAMPLING_RATE;
if (ioctl(audio_fd, SNDCTL_DSP_SPEED, &rate ) == -1 ) {
qWarning("ERROR: DSP_SPEED %s", (QString(strerror(errno))).ascii());
printf ("ERROR: DSP_SPEED %s\n", strerror(errno));
return false;
}
if (rate != SAMPLING_RATE) {
qWarning("WARNING: driver rounded %d Hz request to %d Hz, off by %f%%\n"
printf ("WARNING: driver rounded %d Hz request to %d Hz, off by %f%%\n"
, 8000, rate, 100*((rate-8000)/8000.0));
}
......@@ -136,16 +136,16 @@ AudioDriversOSS::initDevice (DeviceMode mode) {
audio_buf_info info;
if (mode == WriteOnly) {
if (ioctl(audio_fd, SNDCTL_DSP_GETOSPACE, &info) == -1) {
qWarning("ERROR: GETISPACE %s", (QString(strerror(errno))).ascii());
printf ("ERROR: GETISPACE %s\n", strerror(errno));
return false;
}
} else {
if (ioctl(audio_fd, SNDCTL_DSP_GETISPACE, &info ) == -1) {
qWarning("ERROR: GETOSPACE %s", (QString(strerror(errno))).ascii());
printf ("ERROR: GETOSPACE %s\n", strerror(errno));
return false;
}
}
audio_buf.resize (info.fragsize * sizeof(short));
// audio_buf.resize (info.fragsize * sizeof(short));
devstate = DeviceOpened;
return 0;
......@@ -162,16 +162,17 @@ bool
AudioDriversOSS::openDevice (int exist_fd) {
audio_fd = exist_fd;
if (audio_fd == -1) {
qWarning("ERROR: Open Failed");
printf ("ERROR: Open Failed\n");
return false;
}
audio_buf_info info;
if (ioctl(audio_fd, SNDCTL_DSP_GETISPACE, &info) == -1) {
qWarning("ERROR: GETISPACE %s", (QString(strerror(errno))).ascii());
printf ("ERROR: GETISPACE %s\n", strerror(errno));
return false;
}
audio_buf.resize (info.fragsize * sizeof(short));
// audio_buf.resize (info.fragsize * sizeof(short));
devstate = DeviceOpened;
return true;
......@@ -206,11 +207,11 @@ AudioDriversOSS::readBuffer (void *buf, int read_bytes) {
int
AudioDriversOSS::readBuffer (void *ptr, int bytes) {
if( devstate != DeviceOpened ) {
qWarning("Device Not Open");
printf ("Device Not Open\n");
return false;
}
audio_buf.resize(bytes);
//audio_buf.resize(bytes);
ssize_t count = bytes;
// unsigned char *buf;
......@@ -219,14 +220,37 @@ AudioDriversOSS::readBuffer (void *ptr, int bytes) {
rc = read (audio_fd, ptr, count);
if (rc < 0) {
qWarning("read(): %s", (QString(strerror(errno))).ascii());
printf ("rc < 0 read(): %s\n", strerror(errno));
}
else if (rc != count) {
qWarning("WARNING: asked microphone for %d got %d\n", count, rc);
printf ("WARNING: asked microphone for %d got %d\n", count, rc);
}
return rc;
}
int
AudioDriversOSS::readBuffer (int bytes) {
if( devstate != DeviceOpened ) {
printf ("Device Not Open\n");
return false;
}
audio_buf.resize(bytes);
ssize_t count = bytes;
short *buf;
buf = (short*)audio_buf.getData();
ssize_t rc;
rc = read (audio_fd, buf, count);
if (rc < 0) {
qWarning("read(): %s", (QString(strerror(errno))).ascii());
printf ("rc < 0 read(): %s\n", strerror(errno));
}
else if (rc != count) {
printf ("WARNING: asked microphone for %d got %d\n", count, rc);
}
return rc;
......@@ -235,7 +259,7 @@ AudioDriversOSS::readBuffer (void *ptr, int bytes) {
int
AudioDriversOSS::writeBuffer (void *ptr, int len) {
if (devstate != DeviceOpened ) {
qWarning("Device Not Opened");
printf ("Device Not Opened\n");
return -1;
}
......@@ -252,7 +276,7 @@ AudioDriversOSS::writeBuffer (void *ptr, int len) {
for (;;) {
int a;
if ((a = write(audio_fd, ptr, len)) < 0) {
qWarning("write(): %s", (QString(strerror(errno))).ascii());
printf ("write(): %s\n", strerror(errno));
break;
}
if (a > 0) {
......@@ -263,17 +287,39 @@ AudioDriversOSS::writeBuffer (void *ptr, int len) {
return 1;
}
void
AudioDriversOSS::flushReadBuffer(void) {
unsigned char buf[160];
int
AudioDriversOSS::writeBuffer (void) {
if (devstate != DeviceOpened ) {
printf ("Device Not Opened\n");
return -1;
}
printf("Flushing.\n");
// TODO 160-> variable utilisateur
while(readBuffer(buf, 160) == 160)
;
size_t count = audio_buf.getSize();
short *buf = (short*)audio_buf.getData();
audio_buf_info info;
if (ioctl(audio_fd, SNDCTL_DSP_GETOSPACE, &info) == 0 ) {
if (info.fragstotal - info.fragments > 15) {
// drop the fragment if the buffer starts to fill up
return 1;
}
}
// Loop into write() while buffer not complete.
for (;;) {
int a;
if ((a = write(audio_fd, buf, count)) < 0) {
printf ("write(): %s\n", strerror(errno));
break;
}
if (a > 0) {
return a;
break;
}
}
return 1;
}
unsigned int
AudioDriversOSS::readableBytes(void) {
audio_buf_info info;
......@@ -296,7 +342,7 @@ AudioDriversOSS::readableBytes(void) {
return 0;
}
if (ioctl (audio_fd, SNDCTL_DSP_GETISPACE, &info) == -1) {
qWarning("ERROR: readableBytes %s", (QString(strerror(errno))).ascii());
printf ("ERROR: readableBytes %s\n", strerror(errno));
return 0;
}
......
......@@ -23,11 +23,9 @@
#ifndef _AUDIO_DRIVERS_OSS_H
#define _AUDIO_DRIVERS_OSS_H
#include <qstring.h>
#include "audiodrivers.h"
#define BUF_SIZE 4096
// TODO : a mettre dans config
#define AUDIO_DEVICE "/dev/dsp"
......@@ -41,8 +39,9 @@ public:
int closeDevice (void);
bool openDevice (int);
int writeBuffer (void *, int);
int writeBuffer (void);
int readBuffer (void *, int);
void flushReadBuffer (void);
int readBuffer (int);
unsigned int readableBytes (void);
int audio_fd;
......
......@@ -69,6 +69,7 @@ AudioRtp::createNewSession (SipCall *ca) {
}
RTXThread = new AudioRtpRTX (ca, manager->audiodriver, manager, symetric);
qDebug("Start audio thread !!");
RTXThread->start();
return 0;
......@@ -82,9 +83,7 @@ AudioRtp::closeRtpSession (SipCall *ca) {
if (RTXThread != NULL) {
// Wait for them...and delete.
qDebug ("Thread audio JOIN ...");
RTXThread->join();
qDebug ("Thread audio JOIN !!!");
// RTXThread->join();
delete RTXThread;
RTXThread = NULL;
}
......@@ -117,6 +116,7 @@ AudioRtpRTX::AudioRtpRTX (SipCall *sipcall, AudioDrivers *driver,
}
AudioRtpRTX::~AudioRtpRTX () {
this->terminate();
if (!sym) {
if (sessionRecv != NULL) {
delete sessionRecv;
......@@ -241,6 +241,8 @@ AudioRtpRTX::run (void) {
// Send session
////////////////////////////
if (!manager->mute) {
// i = audioDevice->readBuffer (320);
// data_from_mic = (short*)manager->audiodriver->audio_buf.getData();
i = audioDevice->readBuffer (data_from_mic, 320);
} else {
// When IP-phone user click on mute button, we read buffer of a
......@@ -284,7 +286,10 @@ AudioRtpRTX::run (void) {
adu->getSize());
// Write decoded data to sound device
manager->audiodriver->audio_buf.resize(expandedSize);
manager->audiodriver->audio_buf.setData (data_for_speakers);
i = audioDevice->writeBuffer (data_for_speakers, expandedSize);
// i = audioDevice->writeBuffer ();
delete adu;
......
/****************************************************************************
** Form implementation generated from reading ui file 'configurationpanel.ui'
**
** Created: Thu Jan 13 18:34:00 2005
** Created: Tue Jan 18 14:45:52 2005
** by: The User Interface Compiler ($Id$)
**
** WARNING! All changes made in this file will be lost!
......
/****************************************************************************
** Form interface generated from reading ui file 'configurationpanel.ui'
**
** Created: Thu Jan 13 18:34:00 2005
** Created: Tue Jan 18 14:45:52 2005
** by: The User Interface Compiler ($Id$)
**
** WARNING! All changes made in this file will be lost!
......
......@@ -48,7 +48,6 @@ using namespace std;
Manager::Manager (QString *Dc = NULL) {
DirectCall = Dc;
bool exist;
for (int i = 0; i < NUMBER_OF_LINES; i++) {
phLines[i] = new PhoneLine ();
}
......@@ -74,8 +73,8 @@ Manager::Manager (QString *Dc = NULL) {
b_ringtone = false;
if (! DirectCall->isNull()) {
qWarning ("Direct call.....");
phonegui->lcd->textBuffer = DirectCall ;
phonegui->dial();
gui()->lcd->textBuffer = DirectCall ;
gui()->dial();
}
if (!exist){
......@@ -228,7 +227,6 @@ Manager::actionHandle (int lineNumber, int action) {
sip->manageActions (lineNumber, ANSWER_CALL);
this->ring(false);
gui()->lcd->setStatus("Connected");
qDebug("Start timer call");
gui()->startCallTimer(lineNumber);
break;
......@@ -244,9 +242,7 @@ Manager::actionHandle (int lineNumber, int action) {
case ONHOLD_CALL:
if (sip->call[lineNumber] != NULL) {
qDebug("Manager ONHOLD: call[%d] = 0x%X",
(unsigned int)lineNumber, sip->call[lineNumber]);
gui()->lcd->setStatus(ONHOLD_STATUS);
//gui()->lcd->setStatus(ONHOLD_STATUS);
sip->manageActions (lineNumber, ONHOLD_CALL);
}
break;
......@@ -263,7 +259,7 @@ Manager::actionHandle (int lineNumber, int action) {
case CANCEL_CALL:
sip->manageActions (lineNumber, CANCEL_CALL);
sip->notUsedLine = -1;
//sip->notUsedLine = -1;
break;
default:
......@@ -309,7 +305,7 @@ Manager::findLineNumberNotUsedSIP (void) {
* @param remotetype: event type
*/
void
Manager::handleRemoteEvent (int code, char * reason, int remotetype) {
Manager::handleRemoteEvent (int code, char * reason, int remotetype, int line) {
QString qinfo;
switch (remotetype) {
......@@ -327,8 +323,8 @@ Manager::handleRemoteEvent (int code, char * reason, int remotetype) {
case EXOSIP_CALL_ANSWERED:
if (!gui()->transfer)
gui()->lcd->setStatus("Connected");
// Start call timer
gui()->startCallTimer(gui()->currentLineNumber);
// Start call timer
gui()->startCallTimer(gui()->currentLineNumber);
break;
// Remote callee hangup
......@@ -339,13 +335,13 @@ Manager::handleRemoteEvent (int code, char * reason, int remotetype) {
setCallInProgress(false);
} else {
// Stop call timer
gui()->stopCallTimer(gui()->currentLineNumber);
gui()->stopCallTimer(line);
// set state free pixmap line
gui()->setFreeStateLine(gui()->currentLineNumber);
gui()->setFreeStateLine(line);
// set free line
gui()->setCurrentLineNumber(-1);
}
phLines[line]->setbDial(false);
gui()->lcd->clear(QString("Hung up"));
sip->notUsedLine = -1;
break;
......@@ -375,6 +371,11 @@ Manager::handleRemoteEvent (int code, char * reason, int remotetype) {
}
}
void
Manager::startDialTone (void) {
gui()->dialTone(true);
}
int
Manager::startSound (SipCall *ca) {
return audioRTP->createNewSession(ca);
......@@ -387,7 +388,7 @@ Manager::closeSound (SipCall *ca) {
QString
Manager::bufferTextRender (void) {
return QString(*phonegui->lcd->textBuffer);
return QString(*gui()->lcd->textBuffer);
}
void
......
......@@ -60,7 +60,7 @@ public:
int outgoingNewCall (void);
void actionHandle (int, int);
int findLineNumberNotUsedSIP(void);
void handleRemoteEvent (int, char *, int);
void handleRemoteEvent (int, char *, int, int = -1);
int startSound (SipCall *);
void closeSound (SipCall *);
void selectAudioDriver (void);
......@@ -83,6 +83,7 @@ public:
bool transferedCall (void);
void ringTone (bool);
void startDialTone (void);
private:
bool b_ringing;
......
......@@ -372,7 +372,7 @@ MyDisplay::clear (void) {
void
MyDisplay::clear (const QString &newstatus) {
// Remove everything in the buffer.
// Remove everything in the buffer and set the new status.
this->textBuffer->remove(0, this->textBuffer->length());
setStatus(newstatus);
}
......
......@@ -62,6 +62,7 @@ public:
bool inFunction;
QString *textBuffer;
QString *time;
public slots:
void appendText (const QString &);
......@@ -78,7 +79,6 @@ private:
QImage centerImage; // text zone
QImage overImage;
QString *status;
QString *time;
MyDisplayThread *animationThread;
QtGUIMainWindow *qtgui;
......
/****************************************************************************
** Form implementation generated from reading ui file 'phonebook.ui'
**
** Created: Thu Jan 13 18:33:59 2005
** Created: Tue Jan 18 14:45:51 2005
** by: The User Interface Compiler ($Id$)
**
** WARNING! All changes made in this file will be lost!
......
/****************************************************************************
** Form interface generated from reading ui file 'phonebook.ui'
**
** Created: Thu Jan 13 18:33:59 2005
** Created: Tue Jan 18 14:45:51 2005
** by: The User Interface Compiler ($Id$)
**
** WARNING! All changes made in this file will be lost!
......
......@@ -28,6 +28,7 @@ PhoneLine::PhoneLine (void) {