Skip to content
Snippets Groups Projects
Commit aadb2a64 authored by Emmanuel Milou's avatar Emmanuel Milou
Browse files

Merge branch 'plugins' into debug_threads

Conflicts:

	configure.ac
	src/Makefile.am
parents 25aa4a38 5cec7153
No related branches found
No related tags found
No related merge requests found
Showing
with 1370 additions and 25 deletions
...@@ -4,6 +4,6 @@ ...@@ -4,6 +4,6 @@
aclocal -I m4 aclocal -I m4
libtoolize --force libtoolize --force
autoheader autoheader
autoconf -f autoconf -v -f
automake -a automake -a
./configure $@ ./configure $@
...@@ -2,13 +2,45 @@ ...@@ -2,13 +2,45 @@
# #
# @author: Yun Liu <yun.liu@savoirfairelinux.com> # @author: Yun Liu <yun.liu@savoirfairelinux.com>
# #
# Build sflphone debian packages for Ubuntu 8.04 # Build sflphone rpm packages for Fedora 10 and openSUSE 11
# 1 - The SFLphone package must be build with a specific GnuPG key. Please contact us to have more information about that (<sflphoneteam@savoirfairelinux.com>) # 1 - The SFLphone package must be build with a specific GnuPG key. Please contact us to have more information about that (<sflphoneteam@savoirfairelinux.com>)
# 2. The source code can be teched through anonymous http access. So no need of special access. # 2. The source code can be teched through anonymous http access. So no need of special access.
# 3. After having all the prerequisites, you can run "build-package.sh" to build debian packages for sflphone. # 3. After having all the prerequisites, you can run "build-rpm-package.sh" to build rpm packages for sflphone.
# All the source packages and binary packages will be generated in the current directory. #
# Refer to http://www.sflphone.org for futher information # Refer to http://www.sflphone.org for futher information
# Analyze parameters
if [ "$1" == "--help" ] || [ "$1" == "" ];then
echo -e '\E[34mThis script is used to build sflphone rpm packages on ubuntu series(8.04,8,10,9), Fedora 10 and SUSE 11 platform.'
echo -e '\E[34mYou can add --fedora, --suse or --ubuntu to start packaging.'
echo
echo "The SFLphone package must be build with a specific GnuPG key. Please contact us to have more information about that (<sflphoneteam@savoirfairelinux.com>)"
echo
echo "For fedora and SUSE, you also need to add the following lines to $HOME/.rpmmacros:"
echo -e '\E[32m%_gpg_path /home/yun/.gnupg'
echo -e '\E[32m%_gpg_name Savoir-Faire Linux Inc. (Génération des paquets pour SFLphone) <sflphoneteam@savoirfairelinux.com>'
echo -e '\E[32m%_gpgbin /usr/bin/gpg'
echo
echo -e '\E[34mAfter all these preparations done, you can run ./build-package.sh --platform-name'
echo
echo -e '\E[36mHave fun!'
tput sgr0 # Reset colors to "normal."
echo
exit 1
elif [ $1 == "--fedora" ];then
BUILDDIR=$HOME/rpmbuild
platform="fedora"
elif [ $1 == "--suse" ];then
BUILDDIR=/usr/src/packages
platform="suse"
elif [ $1 == "--ubuntu" ];then
platform="ubuntu"
else
echo "This script can only be used for Ubuntu series, Fedora 10 and SUSE 11 platform. Use --help to get more information."
exit 1
fi
if [ -d "sflphone" ]; then if [ -d "sflphone" ]; then
echo "Directory sflphone already exists. Please remove it first." echo "Directory sflphone already exists. Please remove it first."
exit 1 exit 1
...@@ -22,33 +54,54 @@ git checkout origin/release -b release ...@@ -22,33 +54,54 @@ git checkout origin/release -b release
# Get system parameters # Get system parameters
arch_flag=`getconf -a|grep LONG_BIT | sed -e 's/LONG_BIT\s*//'` arch_flag=`getconf -a|grep LONG_BIT | sed -e 's/LONG_BIT\s*//'`
os_version=`lsb_release -d -s -c | sed -e '1d'` os_version=`lsb_release -d -s -c | sed -e '1d'`
ver=0.9.2
if [ $platform == "ubuntu" ];then
# Generate the changelog, according to the distribution and the git commit messages # Generate the changelog, according to the distribution and the git commit messages
cp debian/changelog.$os_version debian/changelog cp debian/changelog.$os_version debian/changelog
git-dch --debian-branch=release --release git-dch --debian-branch=release --release
fi
cd .. cd ..
# Remove useless git directory # Remove useless git directory
rm sflphone/.git/ -rf rm sflphone/.git/ -rf
# Get the public gpg key to sign the packages
wget -q http://www.sflphone.org/downloads/gpg/sflphone.gpg.asc -O- | gpg --import -
if [ $platform == "ubuntu" ];then
# Copy the appropriate control file based on different archtecture # Copy the appropriate control file based on different archtecture
cp sflphone/debian/control.$os_version sflphone/debian/control cp sflphone/debian/control.$os_version sflphone/debian/control
echo "Building sflphone package on Ubuntu $os_version $arch_flag bit architecture...." echo "Building sflphone package on Ubuntu $os_version $arch_flag bit architecture...."
# Provide prerequisite directories used by debuild # Provide prerequisite directories used by debuild
cp sflphone sflphone-0.9.2 -r cp sflphone sflphone-$ver -r
cp sflphone sflphone-0.9.2.orig -r cp sflphone sflphone-$ver.orig -r
# Get the public gpg key to sign the packages
wget -q http://www.sflphone.org/downloads/gpg/sflphone.gpg.asc -O- | gpg --import -
# Build packages # Build packages
cd sflphone-0.9.2/debian; debuild -k'Savoir-Faire Linux Inc.' cd sflphone-$ver/debian; debuild -k'Savoir-Faire Linux Inc.'
# Post clean
cd ..
rm sflphone-$ver sflphone -rf
echo "Done! All the source packages and binary packages are generated in the current directory"
# Clean else
cd ../.. # Prepare for packaging
rm sflphone-0.9.2/ -rf mv sflphone sflphone-$ver
rm sflphone/ -rf
echo "Building package finished successullly!" cp sflphone-$ver/platform/$platform.spec $BUILDDIR/SPECS/
cp sflphone-$ver/libs/pjproject-1.0/libpj-sfl.pc $BUILDDIR/SOURCES
tar zcvf sflphone-$ver.tar.gz sflphone-$ver
rm sflphone-$ver -rf
mv sflphone-$ver.tar.gz $BUILDDIR/SOURCES
echo "Building sflphone package on $platform $arch_flag bit architecture...."
# Build packages
cd $BUILDDIR/SPECS/
rpmbuild -ba --sign sflphone.spec
echo "Done! All source rpms and binary rpms are stored in $BUILDDIR/SRPMS and $BUILDDIR/RPMS"
fi
...@@ -36,7 +36,10 @@ AC_CONFIG_FILES([src/Makefile \ ...@@ -36,7 +36,10 @@ AC_CONFIG_FILES([src/Makefile \
src/audio/codecs/Makefile src/audio/codecs/Makefile
src/audio/codecs/ilbc/Makefile \ src/audio/codecs/ilbc/Makefile \
src/config/Makefile \ src/config/Makefile \
src/dbus/Makefile ]) src/dbus/Makefile \
src/plug-in/audiorecorder/Makefile \
src/plug-in/Makefile \
src/plug-in/test/Makefile])
dnl Unitary test section dnl Unitary test section
AC_CONFIG_FILES([test/Makefile]) AC_CONFIG_FILES([test/Makefile])
......
# Global variables # Global variables
src=$(top_srcdir) src=$(top_srcdir)
sflcodecdir=$(libdir)/sflphone/codecs sflcodecdir=$(libdir)/sflphone/codecs
sflplugindir=$(libdir)/sflphone/plugins
PJSIP_LIBS = -lpjnath-sfl -lpjsua-sfl -lpjsip-sfl -lpjmedia-sfl -lpjsip-simple-sfl -lpjsip-ua-sfl -lpjmedia-codec-sfl -lpjlib-util-sfl -lpj-sfl PJSIP_LIBS = -lpjnath-sfl -lpjsua-sfl -lpjsip-sfl -lpjmedia-sfl -lpjsip-simple-sfl -lpjsip-ua-sfl -lpjmedia-codec-sfl -lpjlib-util-sfl -lpj-sfl
...@@ -16,5 +17,6 @@ AM_CPPFLAGS = \ ...@@ -16,5 +17,6 @@ AM_CPPFLAGS = \
@SIP_CFLAGS@ \ @SIP_CFLAGS@ \
@DBUSCPP_CFLAGS@ \ @DBUSCPP_CFLAGS@ \
-DCODECS_DIR=\""$(sflcodecdir)"\" \ -DCODECS_DIR=\""$(sflcodecdir)"\" \
-DPLUGINS_DIR=\""$(sflplugindir)"\" \
-DENABLE_TRACE -DENABLE_TRACE
...@@ -13,7 +13,7 @@ IAXSOURCES = ...@@ -13,7 +13,7 @@ IAXSOURCES =
IAXHEADERS = IAXHEADERS =
endif endif
SUBDIRS = audio config dbus SUBDIRS = audio config dbus plug-in
# Add here the cpp files to be build with sflphone # Add here the cpp files to be build with sflphone
sflphoned_SOURCES = \ sflphoned_SOURCES = \
...@@ -75,6 +75,8 @@ libsflphone_la_LIBADD = \ ...@@ -75,6 +75,8 @@ libsflphone_la_LIBADD = \
./audio/libaudio.la \ ./audio/libaudio.la \
./dbus/libdbus.la \ ./dbus/libdbus.la \
./config/libconfig.la \ ./config/libconfig.la \
./plug-in/libplugin.la \
./plug-in/audiorecorder/libaudiorecorder.la \
$(IAX_LIBS) $(IAX_LIBS)
libsflphone_la_SOURCES = libsflphone_la_SOURCES =
/*
* Copyright (C) 2008 Savoir-Faire Linux inc.
* 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
* the Free Software Foundation; either version 3 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 "audiorecord.h"
AudioRecord::AudioRecord(){
sndSmplRate_ = 44100;
channels_ = 1;
byteCounter_ = 0;
}
void AudioRecord::setSndSamplingRate(int smplRate){
sndSmplRate_ = smplRate;
}
void AudioRecord::openFile(std::string fileName, FILE_TYPE type, SOUND_FORMAT format) {
channels_ =1;
fileType_ = type;
byteCounter_ = 0;
sndFormat_ = format;
bool result = false;
if(fileType_ == FILE_RAW){
result = setRawFile( fileName.c_str() );
}
else if (fileType_ == FILE_WAV){
result = setWavFile( fileName.c_str() );
}
}
void AudioRecord::closeFile() {
if (fp == 0) return;
if (fileType_ == FILE_RAW)
fclose(fp);
else if (fileType_ == FILE_WAV)
this->closeWavFile();
}
bool AudioRecord::isOpenFile() {
if(fp)
return true;
else
return false;
}
bool AudioRecord::setRawFile(const char *fileName) {
char name[8192];
strncpy(name, fileName, 8192);
if ( strstr(name, ".raw") == NULL) strcat(name, ".raw");
fp = fopen(name, "wb");
if ( !fp ) {
cout << "AudioRecord: could not create RAW file: " << name << '.';
return false;
}
if ( sndFormat_ != INT16 ) { // TODO need to change INT16 to SINT16
sndFormat_ = INT16;
cout << "AudioRecord: using 16-bit signed integer data format for file " << name << '.';
}
cout << "AudioRecord: creating RAW file: " << name;
return true;
}
bool AudioRecord::setWavFile(const char *fileName) {
char name[8192];
strncpy(name, fileName, 8192);
if ( strstr(name, ".wav") == NULL) strcat(name, ".wav");
fp = fopen(name, "wb");
if ( !fp ) {
cout << "AudioRecord: could not create WAV file: " << name;
return false;
}
struct wavhdr hdr = {"RIF", 44, "WAV", "fmt", 16, 1, 1,
44100, 0, 2, 16, "dat", 0};
hdr.riff[3] = 'F';
hdr.wave[3] = 'E';
hdr.fmt[3] = ' ';
hdr.data[3] = 'a';
hdr.num_chans = channels_;
if ( sndFormat_ == INT16 ) { // TODO need to write INT16 to SINT16
hdr.bits_per_samp = 16;
}
hdr.bytes_per_samp = (SINT16) (channels_ * hdr.bits_per_samp / 8);
hdr.bytes_per_sec = (SINT32) (hdr.sample_rate * hdr.bytes_per_samp);
if ( fwrite(&hdr, 4, 11, fp) != 11 ) {
cout << "AudioRecord: could not write WAV header for file " << name << '.';
return false;
}
cout << "AudioRecord: creating WAV file: " << name;
return true;
}
void AudioRecord::closeWavFile()
{
int bytes_per_sample = 1;
if ( sndFormat_ == INT16 )
bytes_per_sample = 2;
SINT32 bytes = byteCounter_ * channels_ * bytes_per_sample;
fseek(fp, 40, SEEK_SET); // jump to data length
fwrite(&bytes, 4, 1, fp);
bytes = byteCounter_ * channels_ * bytes_per_sample + 44; // + 44 for the wave header
fseek(fp, 4, SEEK_SET); // jump to file size
fwrite(&bytes, 4, 1, fp);
fclose( fp );
}
void AudioRecord::recData(SFLDataFormat* buffer, int nSamples) {
if (fp == 0){
cout << "AudioRecord: Can't record data, a file has not yet been opened!";
return;
}
if ( sndFormat_ == INT16 ) { // TODO change INT16 to SINT16
if (nSamples <= 1){
if ( fwrite(buffer, 2, 1, fp) != 1)
cout << "AudioRecord: Could not record data!";
}
else {
for ( int k=0; k<nSamples; k++ ) {
cout << "Buffer[" << k << "] : " << buffer[k] << "\n";
if ( fwrite(&buffer[k], 2, 1, fp) != 1 )
cout << "AudioRecord: Could not record data!";
}
}
}
byteCounter_ += (unsigned long)(sizeof(buffer) / sizeof(SINT16));
return;
}
/*
* Copyright (C) 2008 Savoir-Faire Linux inc.
* 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
* the Free Software Foundation; either version 3 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 <iostream>
#include <string.h>
#include "global.h"
using namespace std;
// structure for the wave header
struct wavhdr {
char riff[4]; // "RIFF"
SINT32 file_size; // in bytes
char wave[4]; // "WAVE"
char fmt[4]; // "fmt "
SINT32 chunk_size; // in bytes (16 for PCM)
SINT16 format_tag; // 1=PCM, 2=ADPCM, 3=IEEE float, 6=A-Law, 7=Mu-Law
SINT16 num_chans; // 1=mono, 2=stereo
SINT32 sample_rate;
SINT32 bytes_per_sec;
SINT16 bytes_per_samp; // 2=16-bit mono, 4=16-bit stereo
SINT16 bits_per_samp;
char data[4]; // "data"
SINT32 data_length; // in bytes
};
class AudioRecord
{
public:
AudioRecord();
void setSndSamplingRate(int smplRate);
/**
* Check if no otehr file is opened, then create a new one
* @param fileName A string containing teh file (with/without extension)
* @param type The sound file format (FILE_RAW, FILE_WAVE)
* @param format Internal sound format (INT16 / INT32)
*/
void openFile(std::string fileName, FILE_TYPE type, SOUND_FORMAT format);
/**
* Close the opend recording file. If wave: cout the number of byte
*/
void closeFile();
/**
* Check if a file is already opened
*/
bool isOpenFile();
/**
* Record a chunk of data in an openend file
* @param buffer The data chunk to be recorded
* @param nSamples Number of samples (number of bytes) to be recorded
*/
void recData(SFLDataFormat* buffer, int nSamples); // TODO ad the data to rec
protected:
/**
* Set the header for raw files
*/
bool setRawFile(const char* fileName);
/**
* Set the header for wave files
*/
bool setWavFile(const char* fileName);
/**
* Compute the number of byte recorded and close the file
*/
void closeWavFile();
/**
* Pointer to the recorded file
*/
FILE *fp; //file pointer
/**
* File format (RAW / WAVE)
*/
FILE_TYPE fileType_;
/**
* Sound format (SINT16/SINT32)
*/
SOUND_FORMAT sndFormat_;
/**
* Number of channels
*/
int channels_;
/**
* Number f byte recorded
*/
unsigned long byteCounter_;
/**
* Sampling rate
*/
int sndSmplRate_;
};
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include "audiolayer.h" #include "audiolayer.h"
#include "audiostream.h" #include "audiostream.h"
#include "plug-in/audiorecorder/audiorecord.h"
#include <pulse/pulseaudio.h> #include <pulse/pulseaudio.h>
......
...@@ -37,6 +37,19 @@ ...@@ -37,6 +37,19 @@
typedef float float32; typedef float float32;
typedef short int16; typedef short int16;
//useful typedefs.
typedef signed short SINT16;
typedef signed int SINT32;
typedef unsigned long FILE_TYPE;
typedef unsigned long SOUND_FORMAT;
const FILE_TYPE FILE_RAW = 1;
const FILE_TYPE FILE_WAV = 2;
static const SOUND_FORMAT INT16 = 0x2; // TODO shold change these symbols
static const SOUND_FORMAT INT32 = 0x8;
#define SUCCESS 0 #define SUCCESS 0
#define ASSERT( expected , value) if( value == expected ) return SUCCESS; \ #define ASSERT( expected , value) if( value == expected ) return SUCCESS; \
......
include ../../globals.mak
SUBDIRS=audiorecorder
noinst_LTLIBRARIES = libplugin.la
SUBDIRS=test
libplugin_la_SOURCES = \
pluginmanager.cpp \
librarymanager.cpp
include $(top_srcdir)/globals.mak
noinst_LTLIBRARIES = libaudiorecorder.la
libaudiorecorder_la_SOURCES = \
audiorecord.cpp
/*
* Copyright (C) 2008 Savoir-Faire Linux inc.
* 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
* the Free Software Foundation; either version 3 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 "audiorecord.h"
AudioRecord::AudioRecord(){
sndSmplRate_ = 44100;
channels_ = 1;
byteCounter_ = 0;
}
void AudioRecord::setSndSamplingRate(int smplRate){
sndSmplRate_ = smplRate;
}
void AudioRecord::openFile(std::string fileName, FILE_TYPE type, SOUND_FORMAT format) {
channels_ =1;
fileType_ = type;
byteCounter_ = 0;
sndFormat_ = format;
bool result = false;
if(fileType_ == FILE_RAW){
result = setRawFile( fileName.c_str() );
}
else if (fileType_ == FILE_WAV){
result = setWavFile( fileName.c_str() );
}
}
void AudioRecord::closeFile() {
if (fp == 0) return;
if (fileType_ == FILE_RAW)
fclose(fp);
else if (fileType_ == FILE_WAV)
this->closeWavFile();
}
bool AudioRecord::isOpenFile() {
if(fp)
return true;
else
return false;
}
bool AudioRecord::setRawFile(const char *fileName) {
char name[8192];
strncpy(name, fileName, 8192);
if ( strstr(name, ".raw") == NULL) strcat(name, ".raw");
fp = fopen(name, "wb");
if ( !fp ) {
cout << "AudioRecord: could not create RAW file: " << name << '.';
return false;
}
if ( sndFormat_ != INT16 ) { // TODO need to change INT16 to SINT16
sndFormat_ = INT16;
cout << "AudioRecord: using 16-bit signed integer data format for file " << name << '.';
}
cout << "AudioRecord: creating RAW file: " << name;
return true;
}
bool AudioRecord::setWavFile(const char *fileName) {
char name[8192];
strncpy(name, fileName, 8192);
if ( strstr(name, ".wav") == NULL) strcat(name, ".wav");
fp = fopen(name, "wb");
if ( !fp ) {
cout << "AudioRecord: could not create WAV file: " << name;
return false;
}
struct wavhdr hdr = {"RIF", 44, "WAV", "fmt", 16, 1, 1,
44100, 0, 2, 16, "dat", 0};
hdr.riff[3] = 'F';
hdr.wave[3] = 'E';
hdr.fmt[3] = ' ';
hdr.data[3] = 'a';
hdr.num_chans = channels_;
if ( sndFormat_ == INT16 ) { // TODO need to write INT16 to SINT16
hdr.bits_per_samp = 16;
}
hdr.bytes_per_samp = (SINT16) (channels_ * hdr.bits_per_samp / 8);
hdr.bytes_per_sec = (SINT32) (hdr.sample_rate * hdr.bytes_per_samp);
if ( fwrite(&hdr, 4, 11, fp) != 11 ) {
cout << "AudioRecord: could not write WAV header for file " << name << '.';
return false;
}
cout << "AudioRecord: creating WAV file: " << name;
return true;
}
void AudioRecord::closeWavFile()
{
int bytes_per_sample = 1;
if ( sndFormat_ == INT16 )
bytes_per_sample = 2;
SINT32 bytes = byteCounter_ * channels_ * bytes_per_sample;
fseek(fp, 40, SEEK_SET); // jump to data length
fwrite(&bytes, 4, 1, fp);
bytes = byteCounter_ * channels_ * bytes_per_sample + 44; // + 44 for the wave header
fseek(fp, 4, SEEK_SET); // jump to file size
fwrite(&bytes, 4, 1, fp);
fclose( fp );
}
void AudioRecord::recData(SFLDataFormat* buffer, int nSamples) {
if (fp == 0){
cout << "AudioRecord: Can't record data, a file has not yet been opened!";
return;
}
if ( sndFormat_ == INT16 ) { // TODO change INT16 to SINT16
if (nSamples <= 1){
if ( fwrite(buffer, 2, 1, fp) != 1)
cout << "AudioRecord: Could not record data!";
}
else {
for ( int k=0; k<nSamples; k++ ) {
cout << "Buffer[" << k << "] : " << buffer[k] << "\n";
if ( fwrite(&buffer[k], 2, 1, fp) != 1 )
cout << "AudioRecord: Could not record data!";
}
}
}
byteCounter_ += (unsigned long)(sizeof(buffer) / sizeof(SINT16));
return;
}
/*
* Copyright (C) 2008 Savoir-Faire Linux inc.
* 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
* the Free Software Foundation; either version 3 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 <iostream>
#include <string.h>
#include "global.h"
using namespace std;
// structure for the wave header
struct wavhdr {
char riff[4]; // "RIFF"
SINT32 file_size; // in bytes
char wave[4]; // "WAVE"
char fmt[4]; // "fmt "
SINT32 chunk_size; // in bytes (16 for PCM)
SINT16 format_tag; // 1=PCM, 2=ADPCM, 3=IEEE float, 6=A-Law, 7=Mu-Law
SINT16 num_chans; // 1=mono, 2=stereo
SINT32 sample_rate;
SINT32 bytes_per_sec;
SINT16 bytes_per_samp; // 2=16-bit mono, 4=16-bit stereo
SINT16 bits_per_samp;
char data[4]; // "data"
SINT32 data_length; // in bytes
};
class AudioRecord
{
public:
AudioRecord();
void setSndSamplingRate(int smplRate);
/**
* Check if no otehr file is opened, then create a new one
* @param fileName A string containing teh file (with/without extension)
* @param type The sound file format (FILE_RAW, FILE_WAVE)
* @param format Internal sound format (INT16 / INT32)
*/
void openFile(std::string fileName, FILE_TYPE type, SOUND_FORMAT format);
/**
* Close the opend recording file. If wave: cout the number of byte
*/
void closeFile();
/**
* Check if a file is already opened
*/
bool isOpenFile();
/**
* Record a chunk of data in an openend file
* @param buffer The data chunk to be recorded
* @param nSamples Number of samples (number of bytes) to be recorded
*/
void recData(SFLDataFormat* buffer, int nSamples); // TODO ad the data to rec
protected:
/**
* Set the header for raw files
*/
bool setRawFile(const char* fileName);
/**
* Set the header for wave files
*/
bool setWavFile(const char* fileName);
/**
* Compute the number of byte recorded and close the file
*/
void closeWavFile();
/**
* Pointer to the recorded file
*/
FILE *fp; //file pointer
/**
* File format (RAW / WAVE)
*/
FILE_TYPE fileType_;
/**
* Sound format (SINT16/SINT32)
*/
SOUND_FORMAT sndFormat_;
/**
* Number of channels
*/
int channels_;
/**
* Number f byte recorded
*/
unsigned long byteCounter_;
/**
* Sampling rate
*/
int sndSmplRate_;
};
/*
* Copyright (C) 2009 Savoir-Faire Linux inc.
* Author: Emmanuel Milou <emmanuel.milou@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
* the Free Software Foundation; either version 3 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 "librarymanager.h"
LibraryManager::LibraryManager (const std::string &filename)
: _filename(filename), _handlePtr(NULL)
{
_handlePtr = loadLibrary (filename);
}
LibraryManager::~LibraryManager (void)
{
unloadLibrary ();
}
LibraryManager::LibraryHandle LibraryManager::loadLibrary (const std::string &filename)
{
LibraryHandle pluginHandlePtr = NULL;
const char *error;
_debug("Loading dynamic library %s\n", filename.c_str());
/* Load the library */
pluginHandlePtr = dlopen( filename.c_str(), RTLD_LAZY );
if( !pluginHandlePtr ) {
error = dlerror();
_debug("Error while opening plug-in: %s\n", error);
return NULL;
}
dlerror();
return pluginHandlePtr;
}
int LibraryManager::unloadLibrary ()
{
if (_handlePtr == NULL)
return 1;
_debug("Unloading dynamic library ...\n");
dlclose( _handlePtr );
if (dlerror())
{
_debug("Error unloading the library : %s\n...", dlerror());
return 1;
}
return 0;
}
int LibraryManager::resolveSymbol (const std::string &symbol, SymbolHandle *symbolPtr)
{
SymbolHandle sy = 0;
if (_handlePtr){
try {
sy = dlsym(_handlePtr, symbol.c_str());
if(sy != NULL) {
*symbolPtr = sy;
return 0;
}
}
catch (...) {}
throw LibraryManagerException ( _filename, symbol, LibraryManagerException::symbolNotFound);
}
else
return 1;
}
/************************************************************************************************/
LibraryManagerException::LibraryManagerException (const std::string &libraryName, const std::string &details, Reason reason) :
_reason (reason), _details (""), std::runtime_error ("")
{
if (_reason == loadingFailed)
_details = "Error when loading " + libraryName + "\n" + details;
else
_details = "Error when resolving symbol " + details + " in " + libraryName;
}
const char* LibraryManagerException::what () const throw()
{
return _details.c_str();
}
/*
* Copyright (C) 2009 Savoir-Faire Linux inc.
* Author: Emmanuel Milou <emmanuel.milou@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
* the Free Software Foundation; either version 3 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 LIBRARY_MANAGER_H
#define LIBRARY_MANAGER_H
#include "dlfcn.h"
#include <stdexcept>
#include "global.h"
class LibraryManager {
public:
typedef void* LibraryHandle;
typedef void* SymbolHandle;
LibraryManager (const std::string &filename);
~LibraryManager (void);
int resolveSymbol (const std::string &symbol, SymbolHandle *ptr);
int unloadLibrary (void);
protected:
LibraryHandle loadLibrary (const std::string &filename);
private:
std::string _filename;
LibraryHandle _handlePtr;
};
class LibraryManagerException : public std::runtime_error {
public:
typedef enum Reason {
loadingFailed = 0,
symbolNotFound
}Reason;
LibraryManagerException (const std::string &libraryName, const std::string &details, Reason reason);
~LibraryManagerException (void) throw() {}
inline Reason getReason (void) { return _reason; }
const char* what () const throw();
private:
Reason _reason;
std::string _details;
};
#endif // LIBRARY_MANAGER_H
/*
* Copyright (C) 2009 Savoir-Faire Linux inc.
* Author: Emmanuel Milou <emmanuel.milou@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
* the Free Software Foundation; either version 3 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 PLUGIN_H
#define PLUGIN_H
#include "global.h"
#include "pluginmanager.h"
/*
* @file plugin.h
* @brief Define a plugin object
*/
class Plugin {
public:
Plugin( const std::string &name ){
_name = name;
}
virtual ~Plugin() {}
inline std::string getPluginName (void) { return _name; }
/**
* Return the minimal core version required so that the plugin could work
* @return int The version required
*/
virtual int initFunc (PluginInfo **info) = 0;
private:
Plugin &operator =(const Plugin &plugin);
std::string _name;
};
typedef Plugin* createFunc (void);
typedef void destroyFunc (Plugin*);
#endif //PLUGIN_H
/*
* Copyright (C) 2009 Savoir-Faire Linux inc.
* Author: Emmanuel Milou <emmanuel.milou@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
* the Free Software Foundation; either version 3 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 <dirent.h>
#include <dlfcn.h>
#include "pluginmanager.h"
PluginManager* PluginManager::_instance = 0;
PluginManager*
PluginManager::instance()
{
if(!_instance){
return new PluginManager();
}
return _instance;
}
PluginManager::PluginManager()
:_loadedPlugins()
{
_instance = this;
}
PluginManager::~PluginManager()
{
_instance = 0;
}
int
PluginManager::loadPlugins (const std::string &path)
{
std::string pluginDir, current;
DIR *dir;
dirent *dirStruct;
LibraryManager *library;
Plugin *plugin;
const std::string pDir = "..";
const std::string cDir = ".";
/* The directory in which plugins are dropped. Default: /usr/lib/sflphone/plugins/ */
( path == "" )? pluginDir = std::string(PLUGINS_DIR).append("/"):pluginDir = path;
_debug("Loading plugins from %s...\n", pluginDir.c_str());
dir = opendir( pluginDir.c_str() );
/* Test if the directory exists or is readable */
if( dir ){
/* Read the directory */
while( (dirStruct=readdir(dir)) ){
/* Get the name of the current item in the directory */
current = dirStruct->d_name;
/* Test if the current item is not the parent or the current directory */
if( current != pDir && current != cDir ){
/* Load the dynamic library */
library = loadDynamicLibrary( pluginDir + current );
/* Instanciate the plugin object */
if(instanciatePlugin (library, &plugin) != 0)
{
_debug("Error instanciating the plugin ...\n");
return 1;
}
/* Regitering the current plugin */
if(registerPlugin (plugin, library) != 0)
{
_debug("Error registering the plugin ...\n");
return 1;
}
}
}
}
else
return 1;
/* Close the directory */
closedir( dir );
return 0;
}
int
PluginManager::unloadPlugins (void)
{
PluginInfo *info;
if(_loadedPlugins.empty()) return 0;
/* Use an iterator on the loaded plugins map */
pluginMap::iterator iter;
iter = _loadedPlugins.begin();
while( iter != _loadedPlugins.end() ) {
info = iter->second;
if (deletePlugin (info) != 0)
{
_debug("Error deleting the plugin ... \n");
return 1;
}
unloadDynamicLibrary (info->_libraryPtr);
if (unregisterPlugin (info) != 0)
{
_debug("Error unregistering the plugin ... \n");
return 1;
}
iter++;
}
return 0;
}
bool
PluginManager::isPluginLoaded (const std::string &name)
{
if(_loadedPlugins.empty()) return false;
/* Use an iterator on the loaded plugins map */
pluginMap::iterator iter;
iter = _loadedPlugins.find (name);
/* Returns map::end if the specified key has not been found */
if(iter==_loadedPlugins.end())
return false;
/* Returns the plugin pointer */
return true;
}
LibraryManager*
PluginManager::loadDynamicLibrary (const std::string& filename)
{
/* Load the library through the library manager */
return new LibraryManager (filename);
}
int
PluginManager::unloadDynamicLibrary (LibraryManager *libraryPtr)
{
_debug("Unloading dynamic library ...\n");
/* Close it */
return libraryPtr->unloadLibrary ();
}
int
PluginManager::instanciatePlugin (LibraryManager *libraryPtr, Plugin **plugin)
{
createFunc *createPlugin;
LibraryManager::SymbolHandle symbol;
if (libraryPtr->resolveSymbol ("createPlugin", &symbol) != 0)
return 1;
createPlugin = (createFunc*)symbol;
*plugin = createPlugin();
return 0;
}
int
PluginManager::deletePlugin (PluginInfo *plugin)
{
destroyFunc *destroyPlugin;
LibraryManager::SymbolHandle symbol;
if (plugin->_libraryPtr->resolveSymbol ("destroyPlugin", &symbol) != 0)
return 1;
destroyPlugin = (destroyFunc*)symbol;
/* Call it */
destroyPlugin (plugin->_plugin);
return 0;
}
int
PluginManager::registerPlugin (Plugin *plugin, LibraryManager *library)
{
std::string key;
PluginInfo *p_info;
if( plugin==0 )
return 1;
p_info = new PluginInfo();
/* Retrieve information from the plugin */
plugin->initFunc (&p_info);
key = p_info->_name;
//p_info->_plugin = plugin;
p_info->_libraryPtr = library;
/* Add the data in the loaded plugin map */
_loadedPlugins[ key ] = p_info;
return 0;
}
int
PluginManager::unregisterPlugin (PluginInfo *plugin)
{
pluginMap::iterator iter;
std::string key;
key = plugin->_name;
if (!isPluginLoaded(key))
return 1;
iter = _loadedPlugins.find (key);
_loadedPlugins.erase (iter);
return 0;
}
/*
* Copyright (C) 2009 Savoir-Faire Linux inc.
* Author: Emmanuel Milou <emmanuel.milou@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
* the Free Software Foundation; either version 3 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 PLUGIN_MANAGER_H
#define PLUGIN_MANAGER_H
/*
* @file pluginmanager.h
* @brief Base class of the plugin manager
*/
#include "librarymanager.h"
#include "global.h"
#include <map>
#include <string>
#include <vector>
class Plugin;
typedef struct PluginInfo {
std::string _name;
LibraryManager *_libraryPtr;
Plugin *_plugin;
int _major_version;
int _minor_version;
} PluginInfo;
#include "plugin.h"
class PluginManager {
public:
/**
* Destructor
*/
~PluginManager();
/**
* Returns the unique instance of the plugin manager
*/
static PluginManager* instance();
/**
* Load all the plugins found in a specific directory
* @param path The absolute path to the directory
* @return int The number of items loaded
*/
int loadPlugins (const std::string &path = "");
int unloadPlugins (void);
int instanciatePlugin (LibraryManager* libraryPtr, Plugin** plugin);
/**
* Check if a plugin has been already loaded
* @param name The name of the plugin looked for
* @return bool The pointer on the plugin or NULL if not found
*/
bool isPluginLoaded (const std::string &name);
int registerPlugin (Plugin *plugin, LibraryManager *library);
int unregisterPlugin (PluginInfo *plugin);
int deletePlugin (PluginInfo *plugin);
/**
* Load a unix dynamic/shared library
* @param filename The path to the dynamic/shared library
* @return LibraryManager* A pointer on the library
*/
LibraryManager* loadDynamicLibrary (const std::string &filename);
/**
* Unload a unix dynamic/shared library
* @param LibraryManager* The pointer on the loaded library
*/
int unloadDynamicLibrary (LibraryManager* libraryPtr);
private:
/**
* Default constructor
*/
PluginManager();
/* Map of plugins associated by their string name */
typedef std::map<std::string, PluginInfo*> pluginMap;
pluginMap _loadedPlugins;
/* The unique static instance */
static PluginManager* _instance;
};
#endif //PLUGIN_MANAGER_H
include $(top_srcdir)/globals.mak
PLUGIN_LIB = libplugintest.so
libplugintest_so_SOURCES = pluginTest.cpp
libplugintest_so_CXXFLAGS = -fPIC -g -Wall
libplugintest_so_LDFLAGS = --shared -lc
INSTALL_PLUGIN_RULE = install-libplugintest_so
noinst_PROGRAMS = libplugintest.so
install-exec-local: install-libplugintest_so
uninstall-local: uninstall-libplugintest_so
install-libplugintest_so: libplugintest.so
mkdir -p $(sflplugindir)
$(INSTALL_PROGRAM) libplugintest.so $(sflplugindir)
uninstall-libplugintest_so:
rm -f $(sflplugindir)/libplugintest.so
/*
* Copyright (C) 2009 Savoir-Faire Linux inc.
* Author: Emmanuel Milou <emmanuel.milou@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
* the Free Software Foundation; either version 3 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 "../plugin.h"
#define MAJOR_VERSION 1
#define MINOR_VERSION 0
class PluginTest : public Plugin {
public:
PluginTest( const std::string &name )
:Plugin( name ) {
}
virtual int initFunc (PluginInfo **info) {
(*info)->_plugin = this;
(*info)->_major_version = MAJOR_VERSION;
(*info)->_minor_version = MINOR_VERSION;
(*info)->_name = getPluginName();
return 0;
}
};
extern "C" Plugin* createPlugin (void){
return new PluginTest("mytest");
}
extern "C" void destroyPlugin (Plugin *p){
delete p;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment