FGCom integrated into FlightGear.
Disabled by default at build time.
This commit is contained in:
parent
df4f574951
commit
d03b44b662
448 changed files with 176770 additions and 27 deletions
|
@ -149,6 +149,7 @@ option(WITH_FGPANEL "Set to ON to build the fgpanel application (default)"
|
|||
option(ENABLE_FGVIEWER "Set to ON to build the fgviewer application (default)" ON)
|
||||
option(ENABLE_GPSSMOOTH "Set to ON to build the GPSsmooth application (default)" ON)
|
||||
option(ENABLE_TERRASYNC "Set to ON to build the terrasync application (default)" ON)
|
||||
option(ENABLE_IAX "Set to ON to build the IAXClient library (default)" ON)
|
||||
|
||||
option(ENABLE_FGJS "Set to ON to build the fgjs application (default)" ON)
|
||||
option(ENABLE_JS_DEMO "Set to ON to build the js_demo application (default)" ON)
|
||||
|
@ -347,8 +348,14 @@ include_directories(${OPENSCENEGRAPH_INCLUDE_DIRS}
|
|||
${SIMGEAR_INCLUDE_DIR}
|
||||
${PLIB_INCLUDE_DIR} )
|
||||
|
||||
include_directories(${PROJECT_SOURCE_DIR})
|
||||
include_directories(${PROJECT_SOURCE_DIR}/src)
|
||||
|
||||
if(ENABLE_IAX)
|
||||
include_directories(${PROJECT_SOURCE_DIR}/utils/fgcom/iaxclient/lib)
|
||||
if(WIN32)
|
||||
include_directories(${PROJECT_SOURCE_DIR}/utils/fgcom/iaxclient/lib/libiax2/src)
|
||||
endif()
|
||||
endif()
|
||||
# following is needed, because config.h is include 'bare', whereas
|
||||
# version.h is included as <Include/version.h> - this should be cleaned up
|
||||
include_directories(${PROJECT_BINARY_DIR}/src)
|
||||
|
@ -379,8 +386,8 @@ if (EMBEDDED_SIMGEAR)
|
|||
include_directories(${PROJECT_BINARY_DIR}/simgear)
|
||||
endif(EMBEDDED_SIMGEAR)
|
||||
|
||||
add_subdirectory(src)
|
||||
add_subdirectory(utils)
|
||||
add_subdirectory(src)
|
||||
add_subdirectory(man)
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
|
|
|
@ -1,23 +0,0 @@
|
|||
d 0755 erik user opt/FlightGear-0.9.4/bin opt/FlightGear-0.9.4/bin FlightGear.sw.base_R10k
|
||||
d 0755 erik user opt/FlightGear-0.9.4/bin opt/FlightGear-0.9.4/bin FlightGear.sw.base_R4k
|
||||
f 0755 erik user opt/FlightGear-0.9.4/bin/est-epsilon opt/FlightGear-0.9.4/bin/est-epsilon FlightGear.sw.optional
|
||||
f 0755 erik user opt/FlightGear-0.9.4/bin/fgadmin opt/FlightGear-0.9.4/bin/fgadmin FlightGear.sw.admin removeop("if [ -x $rbase/usr/sbin/iconcatalogedit ]; then chroot $rbase /usr/sbin/iconcatalogedit -remove 'Category:File Name:/opt/FlightGear-0.9.4/bin/fgadmin' -syspage Freeware; fi;") exitop("if [ -x $rbase/usr/sbin/iconcatalogedit ]; then chroot $rbase /usr/sbin/iconcatalogedit -add 'Category:File Name:/opt/FlightGear-0.9.4/bin/fgadmin' -syspage Freeware; fi;")
|
||||
f 0755 erik user opt/FlightGear-0.9.4/bin/fgfs opt/FlightGear-0.9.4/bin/fgfs FlightGear.sw.base_R4k
|
||||
f 0755 erik user opt/FlightGear-0.9.4/bin/fgfs opt/FlightGear-0.9.4/bin/fgfs.10k FlightGear.sw.base_R10k
|
||||
f 0755 erik user opt/FlightGear-0.9.4/bin/fgjs opt/FlightGear-0.9.4/bin/fgjs FlightGear.sw.optional
|
||||
f 0755 erik user opt/FlightGear-0.9.4/bin/fgrun opt/FlightGear-0.9.4/bin/fgrun FlightGear.sw.admin removeop("if [ -x $rbase/usr/sbin/iconcatalogedit ]; then chroot $rbase /usr/sbin/iconcatalogedit -remove 'Category:File Name:/opt/FlightGear-0.9.4/bin/fgrun' -syspage Freeware; fi;") exitop("if [ -x $rbase/usr/sbin/iconcatalogedit ]; then chroot $rbase /usr/sbin/iconcatalogedit -add 'Category:File Name:/opt/FlightGear-0.9.4/bin/fgrun' -syspage Freeware; fi;")
|
||||
f 0755 erik user opt/FlightGear-0.9.4/bin/gl-info opt/FlightGear-0.9.4/bin/gl-info FlightGear.sw.optional
|
||||
f 0755 erik user opt/FlightGear-0.9.4/bin/js_demo opt/FlightGear-0.9.4/bin/js_demo FlightGear.sw.optional
|
||||
f 0755 erik user opt/FlightGear-0.9.4/bin/metar opt/FlightGear-0.9.4/bin/metar FlightGear.sw.optional
|
||||
f 0755 erik user opt/FlightGear-0.9.4/bin/terrasync opt/FlightGear-0.9.4/bin/terrasync FlightGear.sw.terrasync
|
||||
f 0755 erik user opt/FlightGear-0.9.4/bin/yasim opt/FlightGear-0.9.4/bin/yasim FlightGear.sw.optional
|
||||
d 0755 erik user opt/FlightGear-0.9.4/man opt/FlightGear-0.9.4/man FlightGear.man.manpages
|
||||
d 0755 erik user opt/FlightGear-0.9.4/man/man1 opt/FlightGear-0.9.4/man/man1 FlightGear.man.manpages
|
||||
f 0644 erik user opt/FlightGear-0.9.4/man/man1/est-epsilon.1 opt/FlightGear-0.9.4/man/man1/est-epsilon.1 FlightGear.man.manpages
|
||||
f 0644 erik user opt/FlightGear-0.9.4/man/man1/fgfs.1 opt/FlightGear-0.9.4/man/man1/fgfs.1 FlightGear.man.manpages
|
||||
f 0644 erik user opt/FlightGear-0.9.4/man/man1/fgjs.1 opt/FlightGear-0.9.4/man/man1/fgjs.1 FlightGear.man.manpages
|
||||
f 0644 erik user opt/FlightGear-0.9.4/man/man1/gl-info.1 opt/FlightGear-0.9.4/man/man1/gl-info.1 FlightGear.man.manpages
|
||||
f 0644 erik user opt/FlightGear-0.9.4/man/man1/js_demo.1 opt/FlightGear-0.9.4/man/man1/js_demo.1 FlightGear.man.manpages
|
||||
f 0644 erik user opt/FlightGear-0.9.4/man/man1/pstest.1 opt/FlightGear-0.9.4/man/man1/pstest.1 FlightGear.man.manpages
|
||||
d 0755 erik user opt/FlightGear-0.9.4/sbin opt/FlightGear-0.9.4/sbin FlightGear.sw.servers
|
||||
f 0755 erik user opt/FlightGear-0.9.4/sbin/js_server opt/FlightGear-0.9.4/sbin/js_server FlightGear.sw.servers
|
|
@ -40,3 +40,5 @@
|
|||
#cmakedefine FG_JPEG_SERVER
|
||||
|
||||
#cmakedefine SYSTEM_SQLITE
|
||||
|
||||
#cmakedefine ENABLE_IAX
|
||||
|
|
|
@ -91,7 +91,9 @@ if(ENABLE_JSBSIM)
|
|||
|
||||
target_link_libraries(fgfs JSBSim)
|
||||
endif()
|
||||
|
||||
if(ENABLE_IAX)
|
||||
target_link_libraries(fgfs iaxclient_lib ${OPENAL_LIBRARY})
|
||||
endif()
|
||||
if(FG_HAVE_GPERFTOOLS)
|
||||
include_directories(${GooglePerfTools_INCLUDE_DIR})
|
||||
target_link_libraries(fgfs ${GooglePerfTools_LIBRARIES})
|
||||
|
|
|
@ -101,6 +101,7 @@
|
|||
#include <Instrumentation/HUD/HUD.hxx>
|
||||
#include <Cockpit/cockpitDisplayManager.hxx>
|
||||
#include <Network/HTTPClient.hxx>
|
||||
#include <Network/fgcom.hxx>
|
||||
|
||||
#include "fg_init.hxx"
|
||||
#include "fg_io.hxx"
|
||||
|
@ -741,6 +742,13 @@ void fgCreateSubsystems() {
|
|||
globals->add_subsystem("voice", new FGVoiceMgr, SGSubsystemMgr::DISPLAY);
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_IAX
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Initialize the FGCom subsystem.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
globals->add_subsystem("fgcom", new FGCom);
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Initialize the lighting subsystem.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -185,6 +185,7 @@ fgSetDefaults ()
|
|||
fgSetBool("/sim/panel/visibility", true);
|
||||
fgSetBool("/sim/sound/enabled", true);
|
||||
fgSetBool("/sim/sound/working", true);
|
||||
fgSetBool("/sim/fgcom/enabled", false);
|
||||
|
||||
// Flight Model options
|
||||
fgSetString("/sim/flight-model", "jsb");
|
||||
|
@ -1490,6 +1491,10 @@ struct OptionDesc {
|
|||
{"aircraft", true, OPTION_STRING, "/sim/aircraft", false, "", 0 },
|
||||
{"vehicle", true, OPTION_STRING, "/sim/aircraft", false, "", 0 },
|
||||
{"failure", true, OPTION_FUNC | OPTION_MULTI, "", false, "", fgOptFailure },
|
||||
#ifdef ENABLE_IAX
|
||||
{"enable-fgcom", false, OPTION_BOOL, "/sim/fgcom/enabled", true, "", 0 },
|
||||
{"disable-fgcom", false, OPTION_BOOL, "/sim/fgcom/enabled", false, "", 0 },
|
||||
#endif
|
||||
{"com1", true, OPTION_DOUBLE, "/instrumentation/comm[0]/frequencies/selected-mhz", false, "", 0 },
|
||||
{"com2", true, OPTION_DOUBLE, "/instrumentation/comm[1]/frequencies/selected-mhz", false, "", 0 },
|
||||
{"nav1", true, OPTION_FUNC, "", false, "", fgOptNAV1 },
|
||||
|
|
|
@ -55,6 +55,11 @@ set(HEADERS
|
|||
ray.hxx
|
||||
rul.hxx
|
||||
)
|
||||
|
||||
if(ENABLE_IAX)
|
||||
list(APPEND SOURCES fgcom.cxx)
|
||||
list(APPEND HEADERS fgcom.hxx)
|
||||
endif()
|
||||
|
||||
if(FG_JPEG_SERVER)
|
||||
list(APPEND SOURCES jpg-httpd.cxx)
|
||||
|
|
585
src/Network/fgcom.cxx
Normal file
585
src/Network/fgcom.cxx
Normal file
|
@ -0,0 +1,585 @@
|
|||
// fgcom.cxx -- FGCom: Voice communication
|
||||
//
|
||||
// Written by Clement de l'Hamaide, started Mai 2013.
|
||||
//
|
||||
// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include "fgcom.hxx"
|
||||
|
||||
// standard library includes
|
||||
#include <cstdio>
|
||||
|
||||
// simgear includes
|
||||
#include <simgear/compiler.h>
|
||||
#include <simgear/sg_inlines.h>
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
#include <simgear/math/sg_geodesy.hxx>
|
||||
#include <simgear/timing/timestamp.hxx>
|
||||
|
||||
// flightgear includes
|
||||
#include <Main/fg_props.hxx>
|
||||
#include <Main/globals.hxx>
|
||||
#include <ATC/CommStation.hxx>
|
||||
#include <Airports/airport.hxx>
|
||||
#include <Navaids/navlist.hxx>
|
||||
|
||||
#include <utils/iaxclient/lib/iaxclient.h>
|
||||
|
||||
|
||||
#define NUM_CALLS 4
|
||||
#define MAX_RANGE 100.0
|
||||
#define MIN_RANGE 20.0
|
||||
#define DEFAULT_SERVER "fgcom.flightgear.org"
|
||||
#define IAX_DELAY 300 // delay between calls in milliseconds
|
||||
#define TEST_FREQ 910.00
|
||||
#define NULL_ICAO "ZZZZ"
|
||||
|
||||
const int special_freq[] = { // Define some freq who need to be used with NULL_ICAO
|
||||
911000,
|
||||
700000,
|
||||
123450,
|
||||
122750,
|
||||
121500,
|
||||
123500,
|
||||
121000,
|
||||
723340 };
|
||||
|
||||
|
||||
FGCom::FGCom() :
|
||||
_register(true)
|
||||
{
|
||||
_listener_active = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
FGCom::~FGCom()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
void FGCom::bind()
|
||||
{
|
||||
SGPropertyNode *node = fgGetNode("/sim/fgcom", 0, true);
|
||||
_test_node = node->getChild( "test", 0, true );
|
||||
_server_node = node->getChild( "server", 0, true );
|
||||
_enabled_node = node->getChild( "enabled", 0, true );
|
||||
_micBoost_node = node->getChild( "mic-boost", 0, true );
|
||||
_micLevel_node = node->getChild( "mic-level", 0, true );
|
||||
_speakerLevel_node = node->getChild( "speaker-level", 0, true );
|
||||
_selectedInput_node = node->getChild( "device-input", 0, true );
|
||||
_selectedOutput_node = node->getChild( "device-output", 0, true );
|
||||
|
||||
SGPropertyNode *reg_node = node->getChild("register", 0, true);
|
||||
_register_node = reg_node->getChild( "enabled", 0, true );
|
||||
_username_node = reg_node->getChild( "username", 0, true );
|
||||
_password_node = reg_node->getChild( "password", 0, true );
|
||||
|
||||
//_nav0_node = fgGetNode("/instrumentation/nav[0]/frequencies/selected-mhz", true);
|
||||
//_nav1_node = fgGetNode("/instrumentation/nav[1]/frequencies/selected-mhz", true);
|
||||
_comm0_node = fgGetNode("/instrumentation/comm[0]/frequencies/selected-mhz", true);
|
||||
//_comm1_node = fgGetNode("/instrumentation/comm[1]/frequencies/selected-mhz", true);
|
||||
_ptt0_node = fgGetNode("/instrumentation/comm[0]/ptt", true); //FIXME: what about /instrumentation/comm[1]/ptt ?
|
||||
_callsign_node = fgGetNode("/sim/multiplay/callsign", true);
|
||||
|
||||
// Set default values if not provided
|
||||
if ( !_enabled_node->hasValue() )
|
||||
_enabled_node->setBoolValue(true);
|
||||
|
||||
if ( !_test_node->hasValue() )
|
||||
_test_node->setBoolValue(false);
|
||||
|
||||
if ( !_micBoost_node->hasValue() )
|
||||
_micBoost_node->setIntValue(1);
|
||||
|
||||
if ( !_server_node->hasValue() )
|
||||
_server_node->setStringValue(DEFAULT_SERVER);
|
||||
|
||||
if ( !_speakerLevel_node->hasValue() )
|
||||
_speakerLevel_node->setFloatValue(1.0);
|
||||
|
||||
if ( !_micLevel_node->hasValue() )
|
||||
_micLevel_node->setFloatValue(1.0);
|
||||
|
||||
if ( !_register_node->hasValue() )
|
||||
_register_node->setBoolValue(false);
|
||||
|
||||
if ( !_username_node->hasValue() )
|
||||
_username_node->setStringValue("guest");
|
||||
|
||||
if ( !_password_node->hasValue() )
|
||||
_password_node->setStringValue("guest");
|
||||
|
||||
_selectedOutput_node->addChangeListener(this);
|
||||
_selectedInput_node->addChangeListener(this);
|
||||
_speakerLevel_node->addChangeListener(this);
|
||||
_micBoost_node->addChangeListener(this);
|
||||
_micLevel_node->addChangeListener(this);
|
||||
_enabled_node->addChangeListener(this);
|
||||
_comm0_node->addChangeListener(this);
|
||||
//_comm1_node->addChangeListener(this);
|
||||
//_nav0_node->addChangeListener(this);
|
||||
//_nav1_node->addChangeListener(this);
|
||||
_ptt0_node->addChangeListener(this);
|
||||
_test_node->addChangeListener(this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void FGCom::unbind()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
void FGCom::init()
|
||||
{
|
||||
_enabled = _enabled_node->getBoolValue();
|
||||
_server = _server_node->getStringValue();
|
||||
_register = _register_node->getBoolValue();
|
||||
_username = _username_node->getStringValue();
|
||||
_password = _password_node->getStringValue();
|
||||
|
||||
_currentComm0 = _comm0_node->getDoubleValue();
|
||||
//_currentComm1 = _comm1_node->getDoubleValue();
|
||||
//_currentNav0 = _nav0_node->getDoubleValue();
|
||||
//_currentNav1 = _nav1_node->getDoubleValue();
|
||||
|
||||
_comm0Changed = false;
|
||||
//_comm1Changed = false;
|
||||
//_nav0Changed = false;
|
||||
//_nav1Changed = false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void FGCom::postinit()
|
||||
{
|
||||
if( !_enabled ) {
|
||||
return;
|
||||
}
|
||||
|
||||
//WARNING: this _must_ be executed after sound system is totally initialized !
|
||||
if( iaxc_initialize(NUM_CALLS) ) {
|
||||
SG_LOG(SG_IO, SG_ALERT, "FGCom: cannot initialize iaxclient!");
|
||||
_enabled = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// FIXME: To be implemented in IAX audio driver
|
||||
//iaxc_mic_boost_set( _micBoost_node->getIntValue() );
|
||||
iaxc_set_formats( IAXC_FORMAT_GSM, IAXC_FORMAT_GSM );
|
||||
iaxc_start_processing_thread ();
|
||||
|
||||
if ( _register ) {
|
||||
_regId = iaxc_register( const_cast<char*>(_username.c_str()),
|
||||
const_cast<char*>(_password.c_str()),
|
||||
const_cast<char*>(_server.c_str()) );
|
||||
if( _regId == -1 ) {
|
||||
SG_LOG(SG_IO, SG_INFO, "FGCom: cannot register iaxclient!");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Here we will create the list of available audio devices
|
||||
Each audio device has a name, an ID, and a list of capabilities
|
||||
If an audio device can output sound, available-output=true
|
||||
If an audio device can input sound, available-input=true
|
||||
|
||||
/sim/fgcom/selected-input (int)
|
||||
/sim/fgcom/selected-output (int)
|
||||
|
||||
/sim/fgcom/device[n]/id (int)
|
||||
/sim/fgcom/device[n]/name (string)
|
||||
/sim/fgcom/device[n]/available-input (bool)
|
||||
/sim/fgcom/device[n]/available-output (bool)
|
||||
*/
|
||||
|
||||
//FIXME: OpenAL driver use an hard-coded device
|
||||
// so all following is unused finally until someone
|
||||
// implement "multi-device" support in IAX audio driver
|
||||
SGPropertyNode *node = fgGetNode("/sim/fgcom", 0, true);
|
||||
|
||||
struct iaxc_audio_device *devs;
|
||||
int nDevs, input, output, ring;
|
||||
|
||||
iaxc_audio_devices_get(&devs,&nDevs, &input, &output, &ring);
|
||||
|
||||
for(int i=0; i<nDevs; i++ ) {
|
||||
SGPropertyNode *in_node = node->getChild("device", i, true);
|
||||
|
||||
// devID
|
||||
_deviceID_node[i] = in_node->getChild("id", 0, true);
|
||||
_deviceID_node[i]->setIntValue(devs[i].devID);
|
||||
|
||||
// name
|
||||
_deviceName_node[i] = in_node->getChild("name", 0, true);
|
||||
_deviceName_node[i]->setStringValue(devs[i].name);
|
||||
|
||||
// input capability
|
||||
_deviceInput_node[i] = in_node->getChild("available-input", 0, true);
|
||||
if( devs[i].capabilities & IAXC_AD_INPUT )
|
||||
_deviceInput_node[i]->setBoolValue(true);
|
||||
else
|
||||
_deviceInput_node[i]->setBoolValue(false);
|
||||
|
||||
// output capability
|
||||
_deviceOutput_node[i] = in_node->getChild("available-output", 0, true);
|
||||
if( devs[i].capabilities & IAXC_AD_OUTPUT )
|
||||
_deviceOutput_node[i]->setBoolValue(true);
|
||||
else
|
||||
_deviceOutput_node[i]->setBoolValue(false);
|
||||
|
||||
// use default device at start
|
||||
if( devs[i].capabilities & IAXC_AD_INPUT_DEFAULT )
|
||||
_selectedInput_node->setIntValue(devs[i].devID);
|
||||
if( devs[i].capabilities & IAXC_AD_OUTPUT_DEFAULT )
|
||||
_selectedOutput_node->setIntValue(devs[i].devID);
|
||||
}
|
||||
|
||||
iaxc_millisleep(50);
|
||||
|
||||
// Do the first call at start
|
||||
const double freq = _comm0_node->getDoubleValue();
|
||||
std::string num = computePhoneNumber(freq, getAirportCode(freq));
|
||||
if( num.size() > 0 ) {
|
||||
SG_LOG( SG_IO, SG_INFO, "FGCom comm[0] number=" << num );
|
||||
_callComm0 = iaxc_call(num.c_str());
|
||||
}
|
||||
if( _callComm0 == -1 )
|
||||
SG_LOG( SG_IO, SG_ALERT, "FGCom cannot call selected freq" );
|
||||
}
|
||||
|
||||
|
||||
|
||||
void FGCom::updateCall(bool& changed, int& callNo, double freqMHz)
|
||||
{
|
||||
if (!changed) {
|
||||
if( !isInRange(freqMHz) ) {
|
||||
iaxc_dump_call_number(callNo);
|
||||
callNo = -1;
|
||||
return;
|
||||
} else {
|
||||
if(callNo != -1)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
SG_LOG( SG_IO, SG_INFO, "FGCom manage change" );
|
||||
changed = false; // FIXME, out-params are confusing
|
||||
|
||||
if( callNo != -1 ) {
|
||||
iaxc_dump_call_number( callNo );
|
||||
callNo = -1;
|
||||
}
|
||||
|
||||
if(_p.elapsedMSec() > IAX_DELAY) {
|
||||
std::string num = computePhoneNumber(freqMHz, getAirportCode(freqMHz));
|
||||
if( !isInRange(freqMHz) )
|
||||
return;
|
||||
if( !num.empty() ) {
|
||||
SG_LOG( SG_IO, SG_INFO, "FGCom number=" << num );
|
||||
callNo = iaxc_call_ex(num.c_str(), _callsign.c_str(), NULL, 0 /* no video */);
|
||||
|
||||
if( callNo == -1 )
|
||||
SG_LOG( SG_IO, SG_ALERT, "FGCom cannot call selected freq" );
|
||||
}
|
||||
} else {
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void FGCom::update(double dt)
|
||||
{
|
||||
if ( !_enabled ) {
|
||||
return;
|
||||
}
|
||||
// For now we manage FGCom for only one freq because IAXClient
|
||||
// is not able to handle multiple calls at same time.
|
||||
updateCall(_comm0Changed, _callComm0, _comm0_node->getDoubleValue());
|
||||
// updateCall(_comm1Changed, _callComm1, _comm1_node->getDoubleValue());
|
||||
// updateCall(_nav0Changed, _callNav0, _nav0_node->getDoubleValue());
|
||||
// updateCall(_nav1Changed, _callNav1, _nav1_node->getDoubleValue());
|
||||
}
|
||||
|
||||
|
||||
|
||||
void FGCom::shutdown()
|
||||
{
|
||||
SG_LOG( SG_IO, SG_INFO, "FGCom shutdown()" );
|
||||
_enabled = false;
|
||||
|
||||
iaxc_unregister(_regId);
|
||||
iaxc_stop_processing_thread();
|
||||
iaxc_shutdown();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void FGCom::valueChanged(SGPropertyNode *prop)
|
||||
{
|
||||
if (prop == _enabled_node) {
|
||||
SG_LOG( SG_IO, SG_INFO, "FGCom enabled= " << prop->getBoolValue() );
|
||||
if( prop->getBoolValue() ) {
|
||||
init();
|
||||
postinit();
|
||||
} else {
|
||||
shutdown();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (prop == _ptt0_node && _enabled) {
|
||||
if( _ptt0_node->getBoolValue() ) {
|
||||
iaxc_input_level_set( _micLevel_node->getFloatValue() ); //0.0 = min , 1.0 = max
|
||||
iaxc_output_level_set( 0.0 );
|
||||
} else {
|
||||
iaxc_input_level_set( 0.0 );
|
||||
iaxc_output_level_set( _speakerLevel_node->getFloatValue() );
|
||||
}
|
||||
}
|
||||
|
||||
if (prop == _test_node) {
|
||||
SG_LOG( SG_IO, SG_INFO, "FGCom test= " << prop->getBoolValue() );
|
||||
testMode( prop->getBoolValue() );
|
||||
return;
|
||||
}
|
||||
|
||||
//FIXME: not implemented in IAX audio driver (audio_openal.c)
|
||||
if (prop == _micBoost_node && _enabled) {
|
||||
int micBoost = prop->getIntValue();
|
||||
SG_LOG( SG_IO, SG_INFO, "FGCom mic-boost= " << micBoost );
|
||||
SG_CLAMP_RANGE<int>( micBoost, 0, 1 );
|
||||
iaxc_mic_boost_set( micBoost ) ; // 0 = enabled , 1 = disabled
|
||||
return;
|
||||
}
|
||||
|
||||
//FIXME: not implemented in IAX audio driver (audio_openal.c)
|
||||
if ((prop == _selectedInput_node || prop == _selectedOutput_node) && _enabled) {
|
||||
int selectedInput = _selectedInput_node->getIntValue();
|
||||
int selectedOutput = _selectedOutput_node->getIntValue();
|
||||
SG_LOG( SG_IO, SG_INFO, "FGCom selected-input= " << selectedInput );
|
||||
SG_LOG( SG_IO, SG_INFO, "FGCom selected-output= " << selectedOutput );
|
||||
iaxc_audio_devices_set(selectedInput, selectedOutput, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (_listener_active)
|
||||
return;
|
||||
|
||||
_listener_active++;
|
||||
|
||||
if (prop == _speakerLevel_node && _enabled) {
|
||||
float speakerLevel = prop->getFloatValue();
|
||||
SG_LOG( SG_IO, SG_INFO, "FGCom speaker-level= " << speakerLevel );
|
||||
SG_CLAMP_RANGE<float>( speakerLevel, 0.0, 1.0 );
|
||||
_speakerLevel_node->setFloatValue(speakerLevel);
|
||||
iaxc_output_level_set(speakerLevel);
|
||||
}
|
||||
|
||||
if (prop == _micLevel_node && _enabled) {
|
||||
float micLevel = prop->getFloatValue();
|
||||
SG_LOG( SG_IO, SG_INFO, "FGCom mic-level= " << micLevel );
|
||||
SG_CLAMP_RANGE<float>( micLevel, 0.0, 1.0 );
|
||||
_micLevel_node->setFloatValue(micLevel);
|
||||
iaxc_input_level_set(micLevel);
|
||||
}
|
||||
|
||||
if (prop == _comm0_node) {
|
||||
if( _currentComm0 != prop->getDoubleValue() ) {
|
||||
SG_LOG( SG_IO, SG_INFO, "FGCom comm[0]/freq= " << prop->getDoubleValue() );
|
||||
_currentComm0 = prop->getDoubleValue();
|
||||
_p.stamp();
|
||||
_comm0Changed = true;
|
||||
}
|
||||
}
|
||||
/*
|
||||
if (prop == _comm1_node) {
|
||||
if( _currentComm1 != prop->getDoubleValue() ) {
|
||||
SG_LOG( SG_IO, SG_INFO, "FGCom comm[1]/freq= " << prop->getDoubleValue() );
|
||||
_currentComm1 = prop->getDoubleValue();
|
||||
_p.stamp();
|
||||
_comm1Changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (prop == _nav0_node) {
|
||||
if( _currentNav0 != prop->getDoubleValue() ) {
|
||||
SG_LOG( SG_IO, SG_INFO, "FGCom nav[0]/freq= " << prop->getDoubleValue() );
|
||||
_currentNav0 = prop->getDoubleValue();
|
||||
_nav0Changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (prop == _nav1_node) {
|
||||
if( _currentNav1 != prop->getDoubleValue() ) {
|
||||
SG_LOG( SG_IO, SG_INFO, "FGCom nav[1]/freq= " << prop->getDoubleValue() );
|
||||
_currentNav1 = prop->getDoubleValue();
|
||||
_nav1Changed = true;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
_listener_active--;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void FGCom::testMode(bool testMode)
|
||||
{
|
||||
if(testMode) {
|
||||
_enabled = false;
|
||||
iaxc_dump_call_number(_callComm0);
|
||||
iaxc_input_level_set( _micLevel_node->getFloatValue() );
|
||||
iaxc_output_level_set( _speakerLevel_node->getFloatValue() );
|
||||
std::string num = computePhoneNumber(TEST_FREQ, NULL_ICAO);
|
||||
if( num.size() > 0 ) {
|
||||
SG_LOG( SG_IO, SG_INFO, "FGCom test mode =" << num );
|
||||
iaxc_millisleep(IAX_DELAY);
|
||||
_callComm0 = iaxc_call(num.c_str());
|
||||
}
|
||||
if( _callComm0 == -1 )
|
||||
SG_LOG( SG_IO, SG_ALERT, "FGCom cannot call selected freq (test mode)" );
|
||||
} else {
|
||||
iaxc_dump_call_number(_callComm0);
|
||||
iaxc_millisleep(IAX_DELAY);
|
||||
_callComm0 = -1;
|
||||
_enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
\param freq The requested frequency e.g 120.825
|
||||
\return The ICAO code as string e.g LFMV
|
||||
*/
|
||||
|
||||
std::string FGCom::getAirportCode(const double& freq)
|
||||
{
|
||||
SGGeod aircraftPos = globals->get_aircraft_position();
|
||||
|
||||
int freqKhz = 10 * static_cast<int>(freq * 100 + 0.25);
|
||||
|
||||
for(size_t i=0; i<sizeof(special_freq)/sizeof(special_freq[0]); i++) { // Check if it's a special freq
|
||||
if(special_freq[i] == freqKhz) {
|
||||
SG_LOG( SG_IO, SG_INFO, "FGCom getAirportCode: " << freqKhz << " is specially associated to " << NULL_ICAO );
|
||||
return NULL_ICAO;
|
||||
}
|
||||
}
|
||||
|
||||
flightgear::CommStation* apt = flightgear::CommStation::findByFreq(freqKhz, aircraftPos);
|
||||
if( !apt ) {
|
||||
SG_LOG( SG_IO, SG_INFO, "FGCom getAirportCode: not found" );
|
||||
return std::string();
|
||||
}
|
||||
SG_LOG( SG_IO, SG_INFO, "FGCom getAirportCode: found " << apt->airport()->ident() );
|
||||
|
||||
_aptPos = apt->geod();
|
||||
return apt->airport()->ident();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
\param freq The requested frequency e.g 112.7
|
||||
\return The ICAO code as string e.g ITS
|
||||
*/
|
||||
/*
|
||||
std::string FGCom::getVorCode(const double& freq) const
|
||||
{
|
||||
SGGeod aircraftPos = globals->get_aircraft_position();
|
||||
FGNavList::TypeFilter filter(FGPositioned::VOR);
|
||||
|
||||
FGNavRecord* vor = FGNavList::findByFreq( freq, aircraftPos, &filter);
|
||||
if( !vor ) {
|
||||
SG_LOG( SG_IO, SG_INFO, "FGCom getVorCode: not found" );
|
||||
return std::string();
|
||||
}
|
||||
SG_LOG( SG_IO, SG_INFO, "FGCom getVorCode: found " << vor->get_ident(); );
|
||||
|
||||
return vor->get_ident();
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
\param freq The requested frequency e.g 120.825
|
||||
\param iaco The associated ICAO code e.g LFMV
|
||||
\return The phone number as string i.e username:password@fgcom.flightgear.org/0176707786120825
|
||||
*/
|
||||
|
||||
std::string FGCom::computePhoneNumber(const double& freq, const std::string& icao) const
|
||||
{
|
||||
if( icao.empty() )
|
||||
return std::string();
|
||||
|
||||
char phoneNumber[256];
|
||||
char exten[32];
|
||||
char tmp[5];
|
||||
|
||||
/*Convert ICAO to ASCII */
|
||||
sprintf( tmp, "%4s", icao.c_str() );
|
||||
|
||||
/*Built the phone number */
|
||||
sprintf( exten,
|
||||
"%02d%02d%02d%02d%02d%06d",
|
||||
01,
|
||||
tmp[0],
|
||||
tmp[1],
|
||||
tmp[2],
|
||||
tmp[3],
|
||||
(int) (freq * 1000 + 0.5) );
|
||||
exten[16] = '\0';
|
||||
|
||||
snprintf( phoneNumber,
|
||||
sizeof (phoneNumber),
|
||||
"%s:%s@%s/%s",
|
||||
_username.c_str(),
|
||||
_password.c_str(),
|
||||
_server.c_str(),
|
||||
exten);
|
||||
|
||||
return phoneNumber;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
\return A boolean value, 1=in range, 0=out of range
|
||||
*/
|
||||
|
||||
bool FGCom::isInRange(const double &freq) const
|
||||
{
|
||||
SGGeod acftPos = globals->get_aircraft_position();
|
||||
double distNm = SGGeodesy::distanceNm(_aptPos, acftPos);
|
||||
double delta_elevation_ft = fabs(acftPos.getElevationFt() - _aptPos.getElevationFt());
|
||||
double rangeNm = 1.23 * sqrt(delta_elevation_ft);
|
||||
|
||||
if (rangeNm > MAX_RANGE) rangeNm = MAX_RANGE;
|
||||
if (rangeNm < MIN_RANGE) rangeNm = MIN_RANGE;
|
||||
if( distNm > rangeNm ) return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
102
src/Network/fgcom.hxx
Normal file
102
src/Network/fgcom.hxx
Normal file
|
@ -0,0 +1,102 @@
|
|||
#ifndef FG_FGCOM_HXX
|
||||
#define FG_FGCOM_HXX
|
||||
|
||||
// fgcom.hxx -- FGCom: Voice communication
|
||||
//
|
||||
// Written by Clement de l'Hamaide, started Mai 2013.
|
||||
//
|
||||
// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
#include <simgear/structure/subsystem_mgr.hxx>
|
||||
#include <simgear/props/props.hxx>
|
||||
#include <simgear/math/sg_geodesy.hxx>
|
||||
|
||||
class FGCom : public SGSubsystem, public SGPropertyChangeListener
|
||||
{
|
||||
public:
|
||||
FGCom();
|
||||
virtual ~FGCom();
|
||||
|
||||
virtual void bind();
|
||||
virtual void unbind();
|
||||
virtual void init();
|
||||
virtual void postinit();
|
||||
virtual void update(double dt);
|
||||
virtual void valueChanged(SGPropertyNode *prop);
|
||||
virtual void shutdown();
|
||||
|
||||
private:
|
||||
|
||||
SGPropertyNode_ptr _ptt0_node; // instrumentation/nav[0]/ptt
|
||||
//SGPropertyNode_ptr _nav0_node; // instrumentation/nav[0]/frequencies/selected-mhz
|
||||
//SGPropertyNode_ptr _nav1_node; // instrumentation/nav[1]/frequencies/selected-mhz
|
||||
SGPropertyNode_ptr _comm0_node; // instrumentation/comm[0]/frequencies/selected-mhz
|
||||
//SGPropertyNode_ptr _comm1_node; // instrumentation/comm[1]/frequencies/selected-mhz
|
||||
SGPropertyNode_ptr _test_node; // sim/fgcom/test
|
||||
SGPropertyNode_ptr _server_node; // sim/fgcom/server
|
||||
SGPropertyNode_ptr _enabled_node; // sim/fgcom/enabled
|
||||
SGPropertyNode_ptr _micBoost_node; // sim/fgcom/mic-boost
|
||||
SGPropertyNode_ptr _callsign_node; // sim/multiplay/callsign
|
||||
SGPropertyNode_ptr _register_node; // sim/fgcom/register/enabled
|
||||
SGPropertyNode_ptr _username_node; // sim/fgcom/register/username
|
||||
SGPropertyNode_ptr _password_node; // sim/fgcom/register/password
|
||||
SGPropertyNode_ptr _micLevel_node; // sim/fgcom/mic-level
|
||||
SGPropertyNode_ptr _speakerLevel_node; // sim/fgcom/speaker-level
|
||||
SGPropertyNode_ptr _deviceID_node[4]; // sim/fgcom/device[n]/id
|
||||
SGPropertyNode_ptr _deviceName_node[4]; // sim/fgcom/device[n]/name
|
||||
SGPropertyNode_ptr _deviceInput_node[4]; // sim/fgcom/device[n]/available-input
|
||||
SGPropertyNode_ptr _deviceOutput_node[4]; // sim/fgcom/device[n]/available-output
|
||||
SGPropertyNode_ptr _selectedInput_node; // sim/fgcom/device-input
|
||||
SGPropertyNode_ptr _selectedOutput_node; // sim/fgcom/device-output
|
||||
|
||||
|
||||
|
||||
double _currentComm0;
|
||||
//double _currentComm1;
|
||||
//double _currentNav0;
|
||||
//double _currentNav1;
|
||||
//bool _nav0Changed;
|
||||
//bool _nav1Changed;
|
||||
bool _comm0Changed;
|
||||
//bool _comm1Changed;
|
||||
bool _register;
|
||||
bool _enabled;
|
||||
int _regId;
|
||||
//int _callNav0;
|
||||
//int _callNav1;
|
||||
int _callComm0;
|
||||
//int _callComm1;
|
||||
int _listener_active;
|
||||
std::string _server;
|
||||
std::string _callsign;
|
||||
std::string _username;
|
||||
std::string _password;
|
||||
SGTimeStamp _p;
|
||||
SGGeod _aptPos;
|
||||
|
||||
std::string computePhoneNumber(const double& freq, const std::string& icao) const;
|
||||
std::string getAirportCode(const double& freq);
|
||||
//std::string getVorCode(const double& freq) const;
|
||||
SGGeod getAirportPos(const double& freq) const;
|
||||
bool isInRange(const double& freq) const;
|
||||
|
||||
void updateCall(bool& changed, int& callNo, double freqMHz);
|
||||
void testMode(bool testMode);
|
||||
|
||||
};
|
||||
|
||||
#endif // of FG_FGCOM_HXX
|
||||
|
||||
|
|
@ -29,4 +29,10 @@ endif()
|
|||
|
||||
if(ENABLE_TERRASYNC)
|
||||
add_subdirectory(TerraSync)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(ENABLE_IAX)
|
||||
add_subdirectory(iaxclient/lib)
|
||||
# add_subdirectory(iaxclient)
|
||||
message(STATUS "IAXClient: ENABLED")
|
||||
endif()
|
||||
|
|
515
utils/iaxclient/COPYING.LIB
Normal file
515
utils/iaxclient/COPYING.LIB
Normal file
|
@ -0,0 +1,515 @@
|
|||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
|
||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the Lesser GPL. It also counts
|
||||
as the successor of the GNU Library Public License, version 2, hence
|
||||
the version number 2.1.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Lesser General Public License, applies to some
|
||||
specially designated software packages--typically libraries--of the
|
||||
Free Software Foundation and other authors who decide to use it. You
|
||||
can use it too, but we suggest you first think carefully about whether
|
||||
this license or the ordinary General Public License is the better
|
||||
strategy to use in any particular case, based on the explanations
|
||||
below.
|
||||
|
||||
When we speak of free software, we are referring to freedom of use,
|
||||
not price. Our General Public Licenses are designed to make sure that
|
||||
you have the freedom to distribute copies of free software (and charge
|
||||
for this service if you wish); that you receive source code or can get
|
||||
it if you want it; that you can change the software and use pieces of
|
||||
it in new free programs; and that you are informed that you can do
|
||||
these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
distributors to deny you these rights or to ask you to surrender these
|
||||
rights. These restrictions translate to certain responsibilities for
|
||||
you if you distribute copies of the library or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link other code with the library, you must provide
|
||||
complete object files to the recipients, so that they can relink them
|
||||
with the library after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
We protect your rights with a two-step method: (1) we copyright the
|
||||
library, and (2) we offer you this license, which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
To protect each distributor, we want to make it very clear that
|
||||
there is no warranty for the free library. Also, if the library is
|
||||
modified by someone else and passed on, the recipients should know
|
||||
that what they have is not the original version, so that the original
|
||||
author's reputation will not be affected by problems that might be
|
||||
introduced by others.
|
||||
^L
|
||||
Finally, software patents pose a constant threat to the existence of
|
||||
any free program. We wish to make sure that a company cannot
|
||||
effectively restrict the users of a free program by obtaining a
|
||||
restrictive license from a patent holder. Therefore, we insist that
|
||||
any patent license obtained for a version of the library must be
|
||||
consistent with the full freedom of use specified in this license.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the
|
||||
ordinary GNU General Public License. This license, the GNU Lesser
|
||||
General Public License, applies to certain designated libraries, and
|
||||
is quite different from the ordinary General Public License. We use
|
||||
this license for certain libraries in order to permit linking those
|
||||
libraries into non-free programs.
|
||||
|
||||
When a program is linked with a library, whether statically or using
|
||||
a shared library, the combination of the two is legally speaking a
|
||||
combined work, a derivative of the original library. The ordinary
|
||||
General Public License therefore permits such linking only if the
|
||||
entire combination fits its criteria of freedom. The Lesser General
|
||||
Public License permits more lax criteria for linking other code with
|
||||
the library.
|
||||
|
||||
We call this license the "Lesser" General Public License because it
|
||||
does Less to protect the user's freedom than the ordinary General
|
||||
Public License. It also provides other free software developers Less
|
||||
of an advantage over competing non-free programs. These disadvantages
|
||||
are the reason we use the ordinary General Public License for many
|
||||
libraries. However, the Lesser license provides advantages in certain
|
||||
special circumstances.
|
||||
|
||||
For example, on rare occasions, there may be a special need to
|
||||
encourage the widest possible use of a certain library, so that it
|
||||
becomes
|
||||
a de-facto standard. To achieve this, non-free programs must be
|
||||
allowed to use the library. A more frequent case is that a free
|
||||
library does the same job as widely used non-free libraries. In this
|
||||
case, there is little to gain by limiting the free library to free
|
||||
software only, so we use the Lesser General Public License.
|
||||
|
||||
In other cases, permission to use a particular library in non-free
|
||||
programs enables a greater number of people to use a large body of
|
||||
free software. For example, permission to use the GNU C Library in
|
||||
non-free programs enables many more people to use the whole GNU
|
||||
operating system, as well as its variant, the GNU/Linux operating
|
||||
system.
|
||||
|
||||
Although the Lesser General Public License is Less protective of the
|
||||
users' freedom, it does ensure that the user of a program that is
|
||||
linked with the Library has the freedom and the wherewithal to run
|
||||
that program using a modified version of the Library.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
^L
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library or other
|
||||
program which contains a notice placed by the copyright holder or
|
||||
other authorized party saying it may be distributed under the terms of
|
||||
this Lesser General Public License (also called "this License").
|
||||
Each licensee is addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, complete source code means
|
||||
all the source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control
|
||||
compilation
|
||||
and installation of the library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete source code as you receive it, in any medium, provided that
|
||||
you conspicuously and appropriately publish on each copy an
|
||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||
all the notices that refer to this License and to the absence of any
|
||||
warranty; and distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy,
|
||||
and you may at your option offer warranty protection in exchange for a
|
||||
fee.
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Library, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
^L
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you accompany
|
||||
it with the complete corresponding machine-readable source code, which
|
||||
must be distributed under the terms of Sections 1 and 2 above on a
|
||||
medium customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
^L
|
||||
6. As an exception to the Sections above, you may also combine or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (1) uses at run time a
|
||||
copy of the library already present on the user's computer system,
|
||||
rather than copying library functions into the executable, and (2)
|
||||
will operate properly with a modified version of the library, if
|
||||
the user installs one, as long as the modified version is
|
||||
interface-compatible with the version that the work was made with.
|
||||
|
||||
c) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
d) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
e) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the materials to be distributed need not include anything that is
|
||||
normally distributed (in either source or binary form) with the major
|
||||
components (compiler, kernel, and so on) of the operating system on
|
||||
which the executable runs, unless that component itself accompanies
|
||||
the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
^L
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library is void, and will automatically terminate your
|
||||
rights under this License. However, parties who have received copies,
|
||||
or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties with
|
||||
this License.
|
||||
^L
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply, and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library under this License
|
||||
may add an explicit geographical distribution limitation excluding those
|
||||
countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Lesser General Public License from time to time.
|
||||
Such new versions will be similar in spirit to the present version,
|
||||
but may differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library
|
||||
specifies a version number of this License which applies to it and
|
||||
"any later version", you have the option of following the terms and
|
||||
conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
^L
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
copyrighted by the Free Software Foundation, write to the Free
|
||||
Software Foundation; we sometimes make exceptions for this. Our
|
||||
decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
^L
|
||||
How to Apply These Terms to Your New Libraries
|
||||
|
||||
If you develop a new library, and you want it to be of the greatest
|
||||
possible use to the public, we recommend making it free software that
|
||||
everyone can redistribute and change. You can do so by permitting
|
||||
redistribution under these terms (or, alternatively, under the terms
|
||||
of the ordinary General Public License).
|
||||
|
||||
To apply these terms, attach the following notices to the library.
|
||||
It is safest to attach them to the start of each source file to most
|
||||
effectively convey the exclusion of warranty; and each file should
|
||||
have at least the "copyright" line and a pointer to where the full
|
||||
notice is found.
|
||||
|
||||
|
||||
<one line to give the library's name and a brief idea of what it
|
||||
does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
Also add information on how to contact you by electronic and paper
|
||||
mail.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or
|
||||
your
|
||||
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
library `Frob' (a library for tweaking knobs) written by James
|
||||
Random Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1990
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
||||
|
||||
|
259
utils/iaxclient/README
Normal file
259
utils/iaxclient/README
Normal file
|
@ -0,0 +1,259 @@
|
|||
=======================================================================
|
||||
INTRODUCTION
|
||||
|
||||
This is iaxclient, a portable IAX/IAX2 protocol telephony client library.
|
||||
|
||||
The library itself is in the directory "lib", located in the same
|
||||
directory as this README file.
|
||||
|
||||
The library is designed to build for multiple platforms, and currently
|
||||
supports Linux, MacOSX, Solaris, and Win32 platforms. It is designed to handle
|
||||
the "backend" of IAX telephony operations, including call handling,
|
||||
network protocols, audio encoding/decoding, and audio capture/playback.
|
||||
In it's future, it may be extended to also handle video encode, decode,
|
||||
capture and playback.
|
||||
|
||||
There are also sample clients, which use the library, included here.
|
||||
|
||||
Currently, these are all stored under the "simpleclient" directory, and
|
||||
there are three of them:
|
||||
|
||||
simpleclient/testcall: A simple command-line oriented test program,
|
||||
useful for testing and debugging. It supports
|
||||
all of the same platforms as the library itself.
|
||||
|
||||
simpleclient/wx: A wxWindows (see wxwindows.org) based GUI
|
||||
client. This client also supports all of the
|
||||
same platforms as the library itself.
|
||||
|
||||
simpleclient/WinIAX: A MSVC/Win32 client. This only works with
|
||||
Win32, obviously, and was contributed by
|
||||
Faizan "Tili" Naqvi <faizan@tilizone.com>
|
||||
|
||||
simpleclient/tkiaxphone A command-line client, with a Tcl/Tk GUI
|
||||
client that drives it. It should work on
|
||||
all the platforms
|
||||
|
||||
|
||||
The home page for iaxclient is "http://iaxclient.sourceforge.net/"
|
||||
|
||||
Up-to-date versions of iaxclient are available from a sourceforge SVN
|
||||
repository.
|
||||
|
||||
CVS tarballs are also available as a link from the home page.
|
||||
|
||||
|
||||
=======================================================================
|
||||
LICENSES
|
||||
|
||||
|
||||
The iaxclient library itself, is provided under the terms of the LGPL:
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
MA 02111-1307, USA
|
||||
|
||||
The iaxclient library may also include, when compiled, works distributed
|
||||
under other licenses. See those directories and source files for
|
||||
specifics. These include:
|
||||
|
||||
libiax: (c) 2001 Mark Spencer under the LGPL.
|
||||
libiax2: (c) 2001 Mark Spencer under the LGPL.
|
||||
gsm encoder: Copyright 1992, 1993, 1994 by Jutta Degener
|
||||
and Carsten Bormann, Technische Universitaet Berlin
|
||||
(free license, terms in gsm/copyright)
|
||||
portaudio: Copyright (c) 1999-2000 Ross Bencina and Phil Burk
|
||||
Modified BSD style license, in portaudio/LICENSE.txt
|
||||
|
||||
sox tools: compand.c: Copyright 1999 Chris Bagwell And
|
||||
Nick Bailey
|
||||
resample.c: (not currently used) Copyright 1991
|
||||
Lance Norskog And Sundry Contributors,
|
||||
free licenses in source files.
|
||||
libspeex: (c) various authors
|
||||
BSD-like license.
|
||||
|
||||
|
||||
=======================================================================
|
||||
CONTRIBUTORS:
|
||||
|
||||
IAXCLIENT itself was contributed to by:
|
||||
|
||||
Steve Kann <stevek@stevek.com>
|
||||
Shawn Lawrence <shawn.lawrence@terracecomm.com>
|
||||
Faizan "Tili" Naqvi <faizan@tilizone.com> [Win32 VC++ build/client]
|
||||
Scott Lambert <lambert@lambertfam.org> [FreeBSD build changes]
|
||||
Michael Van Donselaar <mvand@vandonselaar.org> [Win32/MinGW build directions, UI changes, IAXComm phone ]
|
||||
Steven Sokol <ssokol@sokol-associates.com> [ Debugging, Blind Transfer ]
|
||||
Stephan Kauss <Stephan@kauss.org> [ 32-bit alignment for IAX2 ]
|
||||
Stephen Uhler <suhler@sun.com> [Solaris build, tkiaxphone]
|
||||
Steve Underwood <steveu@coppice.org> [PLC implementation from spandsp]
|
||||
Jean-Denis Girard <jd.girard@sysnux.pf> [URL Receive implementation]
|
||||
Panfilov Dmitry <dima@bdpu.org> [Basic ALSA-native audio driver]
|
||||
Mihai Balea <mihai at hates dot ms>
|
||||
Bill Welch <welch1820 at gmail dot com> [Project files for several MS development environments]
|
||||
|
||||
|
||||
In addition to including libiax, IAXCLIENT is also based in part on code
|
||||
included in test clients within libiax itself.
|
||||
|
||||
The included sub-libraries, including libiax, libiax2, gsm, portaudio,
|
||||
and the sox-derived filters, were developed by others, as noted in above
|
||||
and in their sources. We couldn't have built IAXCLIENT (or, it would
|
||||
have been much more difficult!) without the great work from these
|
||||
projects.
|
||||
|
||||
=======================================================================
|
||||
BUILDING THE LIBRARY:
|
||||
|
||||
From the "lib" directory:
|
||||
Linux: type "make" using standard gnu make/gcc
|
||||
FreeBSD: type "gmake" using standard gnu make/gcc
|
||||
MacOSX: type "make" using Apple Dev Tools (gnu make/gcc)
|
||||
Win32: type "make" using Cygwin or Cygwin and MinGW (see below)
|
||||
Solaris: type "gmake" using standard gnu make/gcc
|
||||
|
||||
For a shared library, make clean, then make shared.
|
||||
You should receive a shared library (.dll, .so, .dylib, depending on your platform).
|
||||
|
||||
Win32 Cygwin/MinGW; General:
|
||||
The Win32 build has been tested using the Cygwin Environment, and the
|
||||
MinGW port of the GCC compiler suite. Previously, we only supported
|
||||
compilation with the cygwin _and_ mingw environments installed. We are
|
||||
moving (4/20/2005) to support having the cygwin environment alone, with
|
||||
cygwin's own mingw packages, instead. Compilation of the basic sample
|
||||
clients (but not iaxcomm), works fine with cygwin alone.
|
||||
|
||||
Cygwin Alone:
|
||||
To install cygwin, download and run http://www.cygwin.com/setup.exe
|
||||
You will need to install, in addition to the defaults, these packages:
|
||||
gcc-mingw, gcc-mingw-core, (and for C++ clients, gcc-mingw-g++).
|
||||
[please let the maintainers know if other non-default packages are
|
||||
required].
|
||||
|
||||
There's lots of goodies available from cygwin.
|
||||
|
||||
Once you have this installed, open the cygwin shell, and build. The
|
||||
library makefiles use the -mno-cygwin option, to create native Win32
|
||||
binaries which do _not_ require cygwin.dll, or any special runtimes.
|
||||
|
||||
Cygwin and MinGW:
|
||||
Previously, we advocated installing cygwin environment (for Gnu Make and
|
||||
such), alongside the MinGW distribution itself, as outlined here. This
|
||||
may still be necessary for the Wx-Windows based clients like iaxcomm.
|
||||
|
||||
http://www.mingw.org/mingwfaq.shtml#faq-usingwithcygwin for the
|
||||
MinGW FAQ entry on using MinGW with Cygwin. You do need to make sure
|
||||
that you install the Gnu "make" utility when you install cygwin.
|
||||
|
||||
It should probably also work if you use the MSYS environment and the
|
||||
MinGW compiler, but this configuration is not as well tested.
|
||||
|
||||
=======================================================================
|
||||
LIBRARY ORGANIZATION/DESIGN/CODING CONVENTION NOTES
|
||||
|
||||
The iaxclient library is designed to be a small, simple library that
|
||||
encapsulates all that you need in order to make IAX protocol telephony
|
||||
programs.
|
||||
|
||||
All exported symbols should be prefixed with "iaxc_", to avoid namespace
|
||||
collisions/pollution in programs using this library.
|
||||
|
||||
The header file "iaxclient.h" should contain those declarations needed
|
||||
by client programs, but not rely on other headers (i.e. those from
|
||||
included libraries). The "iaxclient-lib.h" header file is the main
|
||||
header file for the library's internal declarations.
|
||||
|
||||
|
||||
=======================================================================
|
||||
|
||||
SAMPLE CLIENTS
|
||||
|
||||
The "testcall" sample program, provided in the simpleclient/testcall
|
||||
directory (above this "lib" directory) is a simple client program which
|
||||
should also be portable.
|
||||
|
||||
The Makefile for "testcall" will automatically build or update the
|
||||
library when it it built, and the requirements for building testcall are
|
||||
the same as for the library itself.
|
||||
|
||||
|
||||
See README files in the other sample clients for directions for building
|
||||
these.
|
||||
|
||||
=========================================================================
|
||||
|
||||
CODECS
|
||||
|
||||
The codec API is pretty straightforward; just use any of the existing
|
||||
available codecs as a guide. The only place in the main code they
|
||||
interface is the switch in audio_encode.c:create_codec
|
||||
|
||||
ILBC
|
||||
|
||||
Lots of people are enamored with iLBC lately, so I put this together for
|
||||
them. Personally, I prefer speex, because it seems to sound just as
|
||||
good, but has no license restrictions. With proper compilation options
|
||||
(i.e. use it's SSE optimizations), it can be made even faster than the
|
||||
iLBC reference.
|
||||
|
||||
There is glue to build iaxclient with iLBC available in the source, but
|
||||
the source to iLBC itself is _not_ included. This is primarily because
|
||||
of the licensing issues.
|
||||
|
||||
I'm not a lawyer, but it appears that iLBC's license would make it
|
||||
impossible to build iaxclient and link it with a GPL front-end, meaning
|
||||
a library built this way is no longer something that could be considered
|
||||
LGPL. However, you could probably build a client using iLBC and
|
||||
distribute it legally, if you follow the rules in the LGPL. So, this is
|
||||
an issue for you and your legal counsel to figure out.
|
||||
|
||||
To actually build iaxclient with iLBC, though is very easy. Just make a
|
||||
directory under lib named iLBC, and drop the iLBC reference sources into
|
||||
it, then change CODEC_ILBC=0 to CODEC_ILBC=1 in the Makefile, and away
|
||||
you go.
|
||||
|
||||
The source presently is set up for the draft-5 version.
|
||||
|
||||
The iLBC license and software can be found here
|
||||
http://www.ilbcfreeware.org/software.html
|
||||
(sources are also in asterisk).
|
||||
|
||||
=========================================================================
|
||||
|
||||
AUDIO DRIVERS
|
||||
|
||||
The supported audio driver for iaxclient is audio_portaudio; which uses
|
||||
a snapshot of the portaudio v19 library (included, with some minor
|
||||
modifications) to access native audio services on each platform.
|
||||
It includes support for Windows (WMME), Linux (OSS, ALSA, JACK) and
|
||||
MacOS X (CoreAudio).
|
||||
|
||||
There is a (presently broken) WMME-native audio driver which was used
|
||||
during early development, and is no longer maintained. You probably
|
||||
don't want to use this.
|
||||
|
||||
All three Linux PortAudio drivers are enabled by default and supporting
|
||||
libraries need to be present on the system in order to build. If you
|
||||
prefer to disable one or more of the drivers, use the USE_PA_* options
|
||||
in the main Makefile.
|
||||
|
||||
Dmitry Panfilov has contributed a basic native ALSA driver for Linux.
|
||||
Not all features are supported with this driver. It is not compiled in
|
||||
by default, because this would add alsa libraries to the build and link
|
||||
dependencies -- and we don't have a good way of communicating that to
|
||||
applications (like pkg-config stuff, etc). To use it, though, you just
|
||||
need to change AUDIO_ALSA=0 to AUDIO_ALSA=1 in the Makefile.
|
||||
|
||||
|
124
utils/iaxclient/lib/CMakeLists.txt
Normal file
124
utils/iaxclient/lib/CMakeLists.txt
Normal file
|
@ -0,0 +1,124 @@
|
|||
|
||||
# even if we don't select the codec, speex is used for pre-processing audio
|
||||
set(ENABLE_SPEXX 1)
|
||||
|
||||
set(IAXCLIENT_BASE_SOURCES
|
||||
audio_encode.c
|
||||
audio_file.c
|
||||
audio_openal.c
|
||||
codec_alaw.c
|
||||
codec_gsm.c
|
||||
codec_ulaw.c
|
||||
iaxclient_lib.c
|
||||
)
|
||||
|
||||
set(LIBIAX2_SOURCES
|
||||
libiax2/src/iax.c
|
||||
libiax2/src/iax2-parser.c
|
||||
libiax2/src/jitterbuf.c
|
||||
libiax2/src/md5.c
|
||||
)
|
||||
|
||||
set(GSM_SOURCES
|
||||
gsm/src/add.c
|
||||
gsm/src/code.c
|
||||
gsm/src/debug.c
|
||||
gsm/src/decode.c
|
||||
gsm/src/gsm_create.c
|
||||
gsm/src/gsm_decode.c
|
||||
gsm/src/gsm_destroy.c
|
||||
gsm/src/gsm_encode.c
|
||||
gsm/src/gsm_explode.c
|
||||
gsm/src/gsm_implode.c
|
||||
gsm/src/gsm_option.c
|
||||
gsm/src/gsm_print.c
|
||||
gsm/src/long_term.c
|
||||
gsm/src/lpc.c
|
||||
gsm/src/preprocess.c
|
||||
gsm/src/rpe.c
|
||||
gsm/src/short_term.c
|
||||
gsm/src/table.c
|
||||
)
|
||||
|
||||
if (WIN32)
|
||||
list(APPEND IAXCLIENT_BASE_SOURCES winfuncs.c)
|
||||
else()
|
||||
list(APPEND IAXCLIENT_BASE_SOURCES unixfuncs.c)
|
||||
endif(WIN32)
|
||||
|
||||
if (ENABLE_SPEXX)
|
||||
list(APPEND IAXCLIENT_BASE_SOURCES codec_speex.c)
|
||||
|
||||
set(SPEEX_SOURCES
|
||||
libspeex/bits.c
|
||||
libspeex/cb_search.c
|
||||
libspeex/exc_10_16_table.c
|
||||
libspeex/exc_10_32_table.c
|
||||
libspeex/exc_20_32_table.c
|
||||
libspeex/exc_5_256_table.c
|
||||
libspeex/exc_5_64_table.c
|
||||
libspeex/exc_8_128_table.c
|
||||
libspeex/filters.c
|
||||
libspeex/gain_table.c
|
||||
libspeex/gain_table_lbr.c
|
||||
libspeex/hexc_10_32_table.c
|
||||
libspeex/hexc_table.c
|
||||
libspeex/high_lsp_tables.c
|
||||
libspeex/jitter.c
|
||||
libspeex/lbr_48k_tables.c
|
||||
libspeex/lpc.c
|
||||
libspeex/lsp.c
|
||||
libspeex/lsp_tables_nb.c
|
||||
libspeex/ltp.c
|
||||
libspeex/math_approx.c
|
||||
libspeex/mdf.c
|
||||
libspeex/medfilter.c
|
||||
libspeex/misc.c
|
||||
libspeex/modes.c
|
||||
libspeex/nb_celp.c
|
||||
libspeex/preprocess.c
|
||||
libspeex/quant_lsp.c
|
||||
libspeex/sb_celp.c
|
||||
libspeex/smallft.c
|
||||
libspeex/speex.c
|
||||
libspeex/speex_callbacks.c
|
||||
libspeex/speex_header.c
|
||||
libspeex/stereo.c
|
||||
libspeex/vbr.c
|
||||
libspeex/vq.c
|
||||
)
|
||||
|
||||
include_directories(${PROJECT_SOURCE_DIR}/utils/iaxclient/lib/libspeex/include)
|
||||
endif(ENABLE_SPEXX)
|
||||
|
||||
if (ENABLE_ALSA)
|
||||
list(APPEND IAXCLIENT_BASE_SOURCES audio_alsa.c)
|
||||
endif(ENABLE_ALSA)
|
||||
|
||||
if (ENABLE_PORTAUDIO)
|
||||
list(APPEND IAXCLIENT_BASE_SOURCES audio_portaudio.c)
|
||||
endif(ENABLE_PORTAUDIO)
|
||||
|
||||
if (APPLE)
|
||||
add_definitions(-DMACOSX)
|
||||
endif(APPLE)
|
||||
|
||||
list(APPEND IAXCLIENT_BASE_SOURCES spandsp/plc.c)
|
||||
|
||||
add_definitions(-DAUDIO_OPENAL=1)
|
||||
add_definitions(-DLIBIAX)
|
||||
|
||||
# for GSM
|
||||
add_definitions(-DHAS_STRING_H -DHAS_STDLIB_H)
|
||||
add_definitions(-DCODEC_GSM)
|
||||
|
||||
include_directories(${PROJECT_SOURCE_DIR}/utils/iaxclient/lib)
|
||||
include_directories(${PROJECT_SOURCE_DIR}/utils/iaxclient/lib/libiax2/src)
|
||||
include_directories(${PROJECT_SOURCE_DIR}/utils/iaxclient/lib/gsm/inc)
|
||||
|
||||
add_library(iaxclient_lib STATIC
|
||||
${IAXCLIENT_BASE_SOURCES}
|
||||
${GSM_SOURCES}
|
||||
${SPEEX_SOURCES}
|
||||
${LIBIAX2_SOURCES})
|
||||
|
101
utils/iaxclient/lib/TODO
Normal file
101
utils/iaxclient/lib/TODO
Normal file
|
@ -0,0 +1,101 @@
|
|||
TODO items:
|
||||
|
||||
|
||||
1) Audio driver work:
|
||||
Properly abstract audio drivers (currently, we use only
|
||||
portaudio, but we may also want to support others.
|
||||
The most likely candidate here would be zaptel devices.
|
||||
|
||||
Instead of the "switch" statements in the code, define an audio
|
||||
driver structure, with
|
||||
|
||||
- function pointers for actual driver entry points.
|
||||
initialization: (scans available devices, sets up data
|
||||
structures)
|
||||
destruction: (stops everything, cleans up)
|
||||
"start": starts audio for a particular call?
|
||||
"stop": stops audio for a particular call?
|
||||
"playsound": plays a particular sound: can be used for
|
||||
incoming call notification, ringback, dialtone etc?
|
||||
"select": select input and output devices to use?
|
||||
[maybe extend this for zap devices to have "ring", etc
|
||||
functions?]
|
||||
|
||||
|
||||
- Common audio driver data members:
|
||||
a) perhaps an array of devices the driver has found,
|
||||
with for each device, a device name, an
|
||||
indication of whether this device is the default
|
||||
input or output, and whether this device
|
||||
supports input, output, or both.
|
||||
|
||||
For portaudio, we probably want to switch to the "standard"
|
||||
portaudio callback interface, and away from pablio, which isn't
|
||||
really robust enough for our needs once we do this stuff.
|
||||
|
||||
|
||||
|
||||
2) Codecs: (I think that someone is working on this)
|
||||
|
||||
Currently, the library assumes that all calls will be GSM only,
|
||||
and further assumes that all frames will be 20ms. It can
|
||||
control the frame size (within reason) for frames it sends out,
|
||||
but should deal gracefully with incoming frames that aren't
|
||||
20ms.
|
||||
|
||||
Codecs should probably be implemented via a similar set of
|
||||
structure abstractions as audio drivers, above. They also need
|
||||
to handle incoming packets which may switch formats abruptly(?).
|
||||
|
||||
DONE (or, at least, mostly done):
|
||||
==============================================================
|
||||
Call handling
|
||||
currently, the library really only supports one call, and not
|
||||
very well. It should have a collection of calls (either an
|
||||
array, or a linked list), and keep track of the current state of
|
||||
each call.
|
||||
|
||||
An array might be easiest to manage, and would map well to a
|
||||
softphone client. We would then just refer to calls by their
|
||||
index, and a GUI client might present these like call
|
||||
appearances on their display.
|
||||
|
||||
Incoming calls might come in on the first free call appearance,
|
||||
and outgoing calls by default would do the same.
|
||||
|
||||
The state of each call might be similar to phonecore
|
||||
(incoming_incomplete, incoming, outgoing_incomplete, outgoing),
|
||||
but we'd also have to keep track of which call, if any, we
|
||||
currenly have "selected" -- i.e. which one we should connect to
|
||||
the audio system.
|
||||
|
||||
We'd need to send events to the client whenever a call changed
|
||||
"state" in any way.
|
||||
|
||||
We can make the number of calls in the array defined at runtime
|
||||
when the library is initialized. A very simple client like
|
||||
testcall would just ask for a single call, so it wouldn't have
|
||||
to worry about a lot of this.
|
||||
|
||||
Events:
|
||||
We might want to consolidate the (currently three) callbacks
|
||||
that the library makes to clients, into a single callback, that
|
||||
passes back a structure with event info. I was thinking of a
|
||||
structure with an event type, and then a union of different
|
||||
structures depending on the event type.
|
||||
|
||||
The only thing is that we might want to decide whether or not,
|
||||
or how clients will "register" for different event types, even
|
||||
if they're handled through the same callback mechanism.
|
||||
|
||||
Ideally, the library would handle all of the events itself, via
|
||||
some "default" handlers. (I.e. for messages, it might just print
|
||||
them to stdout or stderr. For incoming calls, it might accept
|
||||
them by default).
|
||||
|
||||
So, the choices then are whether the client should register for
|
||||
individual events, or perhaps it can just decline events as they
|
||||
happen, and then the library could handle them.
|
||||
|
||||
|
||||
|
277
utils/iaxclient/lib/audio_alsa.c
Normal file
277
utils/iaxclient/lib/audio_alsa.c
Normal file
|
@ -0,0 +1,277 @@
|
|||
/*
|
||||
* iaxclient: a cross-platform IAX softphone library
|
||||
*
|
||||
* Copyrights:
|
||||
* Copyright (C) 2006 Panfilov Dmitry
|
||||
*
|
||||
* Contributors:
|
||||
* Panfilov Dmitry
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU Lesser (Library) General Public License.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "iaxclient_lib.h"
|
||||
#include <alsa/asoundlib.h>
|
||||
|
||||
static snd_pcm_t *stream_out;
|
||||
static snd_pcm_t *stream_in;
|
||||
|
||||
#define FRAMES_PER_BUFFER 80 /* 80 frames == 10ms */
|
||||
|
||||
|
||||
static int alsa_play_sound(struct iaxc_sound *inSound, int ring) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int alsa_stop_sound(int soundID) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int alsa_start (struct iaxc_audio_driver *d ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int alsa_stop (struct iaxc_audio_driver *d ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void alsa_shutdown_audio()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int alsa_input(struct iaxc_audio_driver *d, void *samples, int *nSamples) {
|
||||
|
||||
/* we don't return partial buffers */
|
||||
long r;
|
||||
long byteread=*nSamples;
|
||||
static int h;
|
||||
*nSamples=0;
|
||||
snd_pcm_start(stream_in);
|
||||
if(h==1) { h=0; return 0;}
|
||||
do{
|
||||
r = snd_pcm_readi(stream_in, samples, byteread);
|
||||
if (r == -EAGAIN){
|
||||
continue;
|
||||
}
|
||||
if (r == - EPIPE) {
|
||||
snd_pcm_prepare(stream_in);
|
||||
continue;
|
||||
}
|
||||
samples += (r * 2);
|
||||
byteread -= r;
|
||||
*nSamples += r;
|
||||
}while(r >=0 && byteread >0);
|
||||
h=1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int alsa_output(struct iaxc_audio_driver *d, void *samples, int nSamples) {
|
||||
|
||||
long r;
|
||||
snd_pcm_start(stream_out);
|
||||
while (nSamples > 0) {
|
||||
r = snd_pcm_writei(stream_out, samples, nSamples);
|
||||
if (r == -EAGAIN){
|
||||
continue;
|
||||
}
|
||||
if (r == - EPIPE) {
|
||||
snd_pcm_prepare(stream_out);
|
||||
continue;
|
||||
}
|
||||
if (r < 0) {
|
||||
fprintf(stderr, "r=%d\n",r);
|
||||
}
|
||||
samples += r * 2;
|
||||
nSamples -= r;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int alsa_select_devices (struct iaxc_audio_driver *d, int input, int output, int ring) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int alsa_selected_devices (struct iaxc_audio_driver *d, int *input, int *output, int *ring) {
|
||||
*input = 0;
|
||||
*output = 0;
|
||||
*ring = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int alsa_destroy (struct iaxc_audio_driver *d )
|
||||
{
|
||||
/* TODO: something should happen here */
|
||||
return 0;
|
||||
}
|
||||
|
||||
double alsa_input_level_get(struct iaxc_audio_driver *d){
|
||||
return -1;
|
||||
}
|
||||
|
||||
double alsa_output_level_get(struct iaxc_audio_driver *d){
|
||||
return -1;
|
||||
}
|
||||
|
||||
int alsa_input_level_set(struct iaxc_audio_driver *d, double level){
|
||||
return -1;
|
||||
}
|
||||
|
||||
int alsa_output_level_set(struct iaxc_audio_driver *d, double level){
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/* initialize audio driver */
|
||||
int alsa_initialize (struct iaxc_audio_driver *d ,int sample_rate) {
|
||||
int i;
|
||||
int err;
|
||||
short buf[128];
|
||||
snd_pcm_hw_params_t *hw_params;
|
||||
snd_pcm_sw_params_t *sw_params;
|
||||
|
||||
if ((err = snd_pcm_open (&stream_out, "default", SND_PCM_STREAM_PLAYBACK, 0)) < 0) {
|
||||
fprintf (stderr, "cannot open audio device default (%s)\n",
|
||||
snd_strerror (err));
|
||||
exit (1);
|
||||
}
|
||||
if ((err = snd_pcm_hw_params_malloc (&hw_params)) < 0) {
|
||||
fprintf (stderr, "cannot allocate hardware parameter structure (%s)\n",
|
||||
snd_strerror (err));
|
||||
exit (1);
|
||||
}
|
||||
if ((err = snd_pcm_hw_params_any (stream_out, hw_params)) < 0) {
|
||||
fprintf (stderr, "cannot initialize hardware parameter structure (%s)\n",
|
||||
snd_strerror (err));
|
||||
exit (1);
|
||||
}
|
||||
if ((err = snd_pcm_hw_params_set_access (stream_out, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) {
|
||||
fprintf (stderr, "cannot set access type (%s)\n",
|
||||
snd_strerror (err));
|
||||
exit (1);
|
||||
}
|
||||
if ((err = snd_pcm_hw_params_set_format (stream_out, hw_params, SND_PCM_FORMAT_S16_LE)) < 0) {
|
||||
fprintf (stderr, "cannot set sample format (%s)\n",
|
||||
snd_strerror (err));
|
||||
exit (1);
|
||||
}
|
||||
if ((err = snd_pcm_hw_params_set_rate (stream_out, hw_params, sample_rate, 0)) < 0) {
|
||||
fprintf (stderr, "cannot set sample rate (%s)\n",
|
||||
snd_strerror (err));
|
||||
exit (1);
|
||||
}
|
||||
if ((err = snd_pcm_hw_params_set_channels (stream_out, hw_params, 1)) < 0) {
|
||||
fprintf (stderr, "cannot set channel count (%s)\n",
|
||||
snd_strerror (err));
|
||||
exit (1);
|
||||
}
|
||||
if ((err = snd_pcm_hw_params (stream_out, hw_params)) < 0) {
|
||||
fprintf (stderr, "cannot set parameters (%s)\n",
|
||||
snd_strerror (err));
|
||||
exit (1);
|
||||
}
|
||||
|
||||
snd_pcm_sw_params_malloc(&sw_params);
|
||||
|
||||
err = snd_pcm_sw_params_current(stream_out, sw_params);
|
||||
if (err < 0) {
|
||||
printf("Unable to determine current swparams for playback: %s\n", snd_strerror(err));
|
||||
return err;
|
||||
}
|
||||
err = snd_pcm_sw_params_set_start_threshold(stream_out, sw_params, 80);
|
||||
if (err < 0) {
|
||||
fprintf(stderr, "Unable to set start threshold mode for playback: %s\n", snd_strerror(err));
|
||||
return err;
|
||||
}
|
||||
err = snd_pcm_sw_params(stream_out, sw_params);
|
||||
if (err < 0) {
|
||||
fprintf(stderr, "Unable to set sw params for playback: %s\n", snd_strerror(err));
|
||||
return err;
|
||||
}
|
||||
|
||||
if ((err = snd_pcm_open (&stream_in, "default", SND_PCM_STREAM_CAPTURE, 0)) < 0) {
|
||||
fprintf (stderr, "cannot open audio device default (%s)\n",
|
||||
snd_strerror (err));
|
||||
exit (1);
|
||||
}
|
||||
if ((err = snd_pcm_hw_params_any (stream_in, hw_params)) < 0) {
|
||||
fprintf (stderr, "cannot initialize hardware parameter structure (%s)\n",
|
||||
snd_strerror (err));
|
||||
exit (1);
|
||||
}
|
||||
if ((err = snd_pcm_hw_params_set_access (stream_in, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) {
|
||||
fprintf (stderr, "cannot set access type (%s)\n",
|
||||
snd_strerror (err));
|
||||
exit (1);
|
||||
}
|
||||
if ((err = snd_pcm_hw_params_set_format (stream_in, hw_params, SND_PCM_FORMAT_S16_LE)) < 0) {
|
||||
fprintf (stderr, "cannot set sample format (%s)\n",
|
||||
snd_strerror (err));
|
||||
exit (1);
|
||||
}
|
||||
if ((err = snd_pcm_hw_params_set_rate (stream_in, hw_params, sample_rate, 0)) < 0) {
|
||||
fprintf (stderr, "cannot set sample rate (%s)\n",
|
||||
snd_strerror (err));
|
||||
exit (1);
|
||||
}
|
||||
if ((err = snd_pcm_hw_params_set_channels (stream_in, hw_params, 1)) < 0) {
|
||||
fprintf (stderr, "cannot set channel count (%s)\n",
|
||||
snd_strerror (err));
|
||||
exit (1);
|
||||
}
|
||||
if ((err = snd_pcm_hw_params (stream_in, hw_params)) < 0) {
|
||||
fprintf (stderr, "cannot set parameters (%s)\n",
|
||||
snd_strerror (err));
|
||||
exit (1);
|
||||
}
|
||||
|
||||
err = snd_pcm_sw_params_current(stream_in, sw_params);
|
||||
if (err < 0) {
|
||||
printf("Unable to determine current swparams for playback: %s\n", snd_strerror(err));
|
||||
return err;
|
||||
}
|
||||
err = snd_pcm_sw_params_set_start_threshold(stream_in, sw_params, 80);
|
||||
if (err < 0) {
|
||||
fprintf(stderr, "Unable to set start threshold mode for playback: %s\n", snd_strerror(err));
|
||||
return err;
|
||||
}
|
||||
err = snd_pcm_sw_params(stream_in, sw_params);
|
||||
if (err < 0) {
|
||||
fprintf(stderr, "Unable to set sw params for playback: %s\n", snd_strerror(err));
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
if ((err = snd_pcm_prepare (stream_in)) < 0) {
|
||||
fprintf (stderr, "cannot prepare audio interface for use (%s)\n",
|
||||
snd_strerror (err));
|
||||
exit (1);
|
||||
}
|
||||
|
||||
if ((err = snd_pcm_prepare (stream_out)) < 0) {
|
||||
fprintf (stderr, "cannot prepare audio interface for use (%s)\n",
|
||||
snd_strerror (err));
|
||||
exit (1);
|
||||
}
|
||||
|
||||
d->initialize = alsa_initialize;
|
||||
d->destroy = alsa_destroy;
|
||||
d->select_devices = alsa_select_devices;
|
||||
d->selected_devices = alsa_selected_devices;
|
||||
d->start = alsa_start;
|
||||
d->stop = alsa_stop;
|
||||
d->output = alsa_output;
|
||||
d->input = alsa_input;
|
||||
d->input_level_get = alsa_input_level_get;
|
||||
d->input_level_set = alsa_input_level_set;
|
||||
d->output_level_get = alsa_output_level_get;
|
||||
d->output_level_set = alsa_output_level_set;
|
||||
d->play_sound = alsa_play_sound;
|
||||
d->stop_sound = alsa_stop_sound;
|
||||
|
||||
return 0;
|
||||
}
|
20
utils/iaxclient/lib/audio_alsa.h
Normal file
20
utils/iaxclient/lib/audio_alsa.h
Normal file
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* iaxclient: a cross-platform IAX softphone library
|
||||
*
|
||||
* Copyrights:
|
||||
* Copyright (C) 2003-2006, Horizon Wimba, Inc.
|
||||
* Copyright (C) 2007, Wimba, Inc.
|
||||
*
|
||||
* Contributors:
|
||||
* Steve Kann <stevek@stevek.com>
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU Lesser (Library) General Public License.
|
||||
*/
|
||||
|
||||
#ifndef _AUDIO_ALSA_H
|
||||
#define _AUDIO_ALSA_H
|
||||
|
||||
int alsa_initialize();
|
||||
|
||||
#endif
|
410
utils/iaxclient/lib/audio_encode.c
Normal file
410
utils/iaxclient/lib/audio_encode.c
Normal file
|
@ -0,0 +1,410 @@
|
|||
/*
|
||||
* iaxclient: a cross-platform IAX softphone library
|
||||
*
|
||||
* Copyrights:
|
||||
* Copyright (C) 2003-2006, Horizon Wimba, Inc.
|
||||
* Copyright (C) 2007, Wimba, Inc.
|
||||
*
|
||||
* Contributors:
|
||||
* Steve Kann <stevek@stevek.com>
|
||||
* Michael Van Donselaar <mvand@vandonselaar.org>
|
||||
* Shawn Lawrence <shawn.lawrence@terracecomm.com>
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU Lesser (Library) General Public License.
|
||||
*/
|
||||
|
||||
#include "audio_encode.h"
|
||||
#include "iaxclient_lib.h"
|
||||
#include "iax-client.h"
|
||||
#ifdef CODEC_GSM
|
||||
#include "codec_gsm.h"
|
||||
#endif
|
||||
#include "codec_ulaw.h"
|
||||
#include "codec_alaw.h"
|
||||
|
||||
#include "codec_speex.h"
|
||||
#include <speex/speex_preprocess.h>
|
||||
|
||||
#ifdef CODEC_ILBC
|
||||
#include "codec_ilbc.h"
|
||||
#endif
|
||||
|
||||
float iaxci_silence_threshold = AUDIO_ENCODE_SILENCE_DB;
|
||||
|
||||
static float input_level = 0.0f;
|
||||
static float output_level = 0.0f;
|
||||
|
||||
static SpeexPreprocessState *st = NULL;
|
||||
static int speex_state_size = 0;
|
||||
static int speex_state_rate = 0;
|
||||
|
||||
int iaxci_filters = IAXC_FILTER_AGC|IAXC_FILTER_DENOISE|IAXC_FILTER_AAGC|IAXC_FILTER_CN;
|
||||
|
||||
/* use to measure time since last audio was processed */
|
||||
static struct timeval timeLastInput ;
|
||||
static struct timeval timeLastOutput ;
|
||||
|
||||
static struct iaxc_speex_settings speex_settings =
|
||||
{
|
||||
1, /* decode_enhance */
|
||||
-1, /* float quality */
|
||||
-1, /* bitrate */
|
||||
0, /* vbr */
|
||||
0, /* abr */
|
||||
3 /* complexity */
|
||||
};
|
||||
|
||||
|
||||
static float vol_to_db(float vol)
|
||||
{
|
||||
/* avoid calling log10() on zero which yields inf or
|
||||
* negative numbers which yield nan */
|
||||
if ( vol <= 0.0f )
|
||||
return AUDIO_ENCODE_SILENCE_DB;
|
||||
else
|
||||
return log10f(vol) * 20.0f;
|
||||
}
|
||||
|
||||
static int do_level_callback()
|
||||
{
|
||||
static struct timeval last = {0,0};
|
||||
struct timeval now;
|
||||
float input_db;
|
||||
float output_db;
|
||||
|
||||
now = iax_tvnow();
|
||||
|
||||
if ( last.tv_sec != 0 && iaxci_usecdiff(&now, &last) < 100000 )
|
||||
return 0;
|
||||
|
||||
last = now;
|
||||
|
||||
/* if input has not been processed in the last second, set to silent */
|
||||
input_db = iaxci_usecdiff(&now, &timeLastInput) < 1000000 ?
|
||||
vol_to_db(input_level) : AUDIO_ENCODE_SILENCE_DB;
|
||||
|
||||
/* if output has not been processed in the last second, set to silent */
|
||||
output_db = iaxci_usecdiff(&now, &timeLastOutput) < 1000000 ?
|
||||
vol_to_db(output_level) : AUDIO_ENCODE_SILENCE_DB;
|
||||
|
||||
iaxci_do_levels_callback(input_db, output_db);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void set_speex_filters()
|
||||
{
|
||||
int i;
|
||||
|
||||
if ( !st )
|
||||
return;
|
||||
|
||||
i = 1; /* always make VAD decision */
|
||||
speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_VAD, &i);
|
||||
i = (iaxci_filters & IAXC_FILTER_AGC) ? 1 : 0;
|
||||
speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_AGC, &i);
|
||||
i = (iaxci_filters & IAXC_FILTER_DENOISE) ? 1 : 0;
|
||||
speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_DENOISE, &i);
|
||||
|
||||
/*
|
||||
* We can tweak these parameters to play with VAD sensitivity.
|
||||
* For now, we use the default values since it seems they are a good starting point.
|
||||
* However, if need be, this is the code that needs to change
|
||||
*/
|
||||
i = 35;
|
||||
speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_PROB_START, &i);
|
||||
i = 20;
|
||||
speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_PROB_CONTINUE, &i);
|
||||
}
|
||||
|
||||
static void calculate_level(short *audio, int len, float *level)
|
||||
{
|
||||
int big_sample = 0;
|
||||
int i;
|
||||
|
||||
for ( i = 0; i < len; i++ )
|
||||
{
|
||||
const int sample = abs(audio[i]);
|
||||
big_sample = sample > big_sample ?
|
||||
sample : big_sample;
|
||||
}
|
||||
|
||||
*level += ((float)big_sample / 32767.0f - *level) / 5.0f;
|
||||
}
|
||||
|
||||
|
||||
static int input_postprocess(void *audio, int len, int rate)
|
||||
{
|
||||
static float lowest_volume = 1.0f;
|
||||
float volume;
|
||||
int silent = 0;
|
||||
|
||||
if ( !st || speex_state_size != len || speex_state_rate != rate )
|
||||
{
|
||||
if (st)
|
||||
speex_preprocess_state_destroy(st);
|
||||
st = speex_preprocess_state_init(len,rate);
|
||||
speex_state_size = len;
|
||||
speex_state_rate = rate;
|
||||
set_speex_filters();
|
||||
}
|
||||
|
||||
calculate_level((short *)audio, len, &input_level);
|
||||
|
||||
/* only preprocess if we're interested in VAD, AGC, or DENOISE */
|
||||
if ( (iaxci_filters & (IAXC_FILTER_DENOISE | IAXC_FILTER_AGC)) ||
|
||||
iaxci_silence_threshold > 0.0f )
|
||||
silent = !speex_preprocess(st, (spx_int16_t *)audio, NULL);
|
||||
|
||||
/* Analog AGC: Bring speex AGC gain out to mixer, with lots of hysteresis */
|
||||
/* use a higher continuation threshold for AAGC than for VAD itself */
|
||||
if ( !silent &&
|
||||
iaxci_silence_threshold != 0.0f &&
|
||||
(iaxci_filters & IAXC_FILTER_AGC) &&
|
||||
(iaxci_filters & IAXC_FILTER_AAGC)
|
||||
)
|
||||
{
|
||||
static int i = 0;
|
||||
|
||||
i++;
|
||||
|
||||
if ( (i & 0x3f) == 0 )
|
||||
{
|
||||
float loudness = st->loudness2;
|
||||
// speex_preprocess_ctl(st, SPEEX_PREPROCESS_GET_AGC_LOUDNESS, &loudness);
|
||||
if ( loudness > 8000.0f || loudness < 4000.0f )
|
||||
{
|
||||
const float level = iaxc_input_level_get();
|
||||
|
||||
if ( loudness > 16000.0f && level > 0.5f )
|
||||
{
|
||||
/* lower quickly if we're really too hot */
|
||||
iaxc_input_level_set(level - 0.2f);
|
||||
}
|
||||
else if ( loudness > 8000.0f && level >= 0.15f )
|
||||
{
|
||||
/* lower less quickly if we're a bit too hot */
|
||||
iaxc_input_level_set(level - 0.1f);
|
||||
}
|
||||
else if ( loudness < 4000.0f && level <= 0.9f )
|
||||
{
|
||||
/* raise slowly if we're cold */
|
||||
iaxc_input_level_set(level + 0.1f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* This is ugly. Basically just don't get volume level if speex thought
|
||||
* we were silent. Just set it to 0 in that case */
|
||||
if ( iaxci_silence_threshold > 0.0f && silent )
|
||||
input_level = 0.0f;
|
||||
|
||||
do_level_callback();
|
||||
|
||||
volume = vol_to_db(input_level);
|
||||
|
||||
if ( volume < lowest_volume )
|
||||
lowest_volume = volume;
|
||||
|
||||
if ( iaxci_silence_threshold > 0.0f )
|
||||
return silent;
|
||||
else
|
||||
return volume < iaxci_silence_threshold;
|
||||
}
|
||||
|
||||
static int output_postprocess(void *audio, int len)
|
||||
{
|
||||
calculate_level((short *)audio, len, &output_level);
|
||||
|
||||
do_level_callback();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct iaxc_audio_codec *create_codec(int format)
|
||||
{
|
||||
switch (format & IAXC_AUDIO_FORMAT_MASK)
|
||||
{
|
||||
#ifdef CODEC_GSM
|
||||
case IAXC_FORMAT_GSM:
|
||||
return codec_audio_gsm_new();
|
||||
#endif
|
||||
case IAXC_FORMAT_ULAW:
|
||||
return codec_audio_ulaw_new();
|
||||
case IAXC_FORMAT_ALAW:
|
||||
return codec_audio_alaw_new();
|
||||
case IAXC_FORMAT_SPEEX:
|
||||
return codec_audio_speex_new(&speex_settings);
|
||||
#ifdef CODEC_ILBC
|
||||
case IAXC_FORMAT_ILBC:
|
||||
return codec_audio_ilbc_new();
|
||||
#endif
|
||||
default:
|
||||
/* ERROR: codec not supported */
|
||||
fprintf(stderr, "ERROR: Codec not supported: %d\n", format);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
EXPORT void iaxc_set_speex_settings(int decode_enhance, float quality,
|
||||
int bitrate, int vbr, int abr, int complexity)
|
||||
{
|
||||
speex_settings.decode_enhance = decode_enhance;
|
||||
speex_settings.quality = quality;
|
||||
speex_settings.bitrate = bitrate;
|
||||
speex_settings.vbr = vbr;
|
||||
speex_settings.abr = abr;
|
||||
speex_settings.complexity = complexity;
|
||||
}
|
||||
|
||||
int audio_send_encoded_audio(struct iaxc_call *call, int callNo, void *data,
|
||||
int format, int samples)
|
||||
{
|
||||
unsigned char outbuf[1024];
|
||||
int outsize = 1024;
|
||||
int silent;
|
||||
int insize = samples;
|
||||
|
||||
/* update last input timestamp */
|
||||
timeLastInput = iax_tvnow();
|
||||
|
||||
silent = input_postprocess(data, insize, 8000);
|
||||
|
||||
if(silent)
|
||||
{
|
||||
if(!call->tx_silent)
|
||||
{ /* send a Comfort Noise Frame */
|
||||
call->tx_silent = 1;
|
||||
if ( iaxci_filters & IAXC_FILTER_CN )
|
||||
iax_send_cng(call->session, 10, NULL, 0);
|
||||
}
|
||||
return 0; /* poof! no encoding! */
|
||||
}
|
||||
|
||||
/* we're going to send voice now */
|
||||
call->tx_silent = 0;
|
||||
|
||||
/* destroy encoder if it is incorrect type */
|
||||
if(call->encoder && call->encoder->format != format)
|
||||
{
|
||||
call->encoder->destroy(call->encoder);
|
||||
call->encoder = NULL;
|
||||
}
|
||||
|
||||
/* just break early if there's no format defined: this happens for the
|
||||
* first couple of frames of new calls */
|
||||
if(format == 0) return 0;
|
||||
|
||||
/* create encoder if necessary */
|
||||
if(!call->encoder)
|
||||
{
|
||||
call->encoder = create_codec(format);
|
||||
}
|
||||
|
||||
if(!call->encoder)
|
||||
{
|
||||
/* ERROR: no codec */
|
||||
fprintf(stderr, "ERROR: Codec could not be created: %d\n", format);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(call->encoder->encode(call->encoder, &insize, (short *)data,
|
||||
&outsize, outbuf))
|
||||
{
|
||||
/* ERROR: codec error */
|
||||
fprintf(stderr, "ERROR: encode error: %d\n", format);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(samples-insize == 0)
|
||||
{
|
||||
fprintf(stderr, "ERROR encoding (no samples output (samples=%d)\n", samples);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Send the encoded audio data back to the app if required
|
||||
// TODO: fix the stupid way in which the encoded audio size is returned
|
||||
if ( iaxc_get_audio_prefs() & IAXC_AUDIO_PREF_RECV_LOCAL_ENCODED )
|
||||
iaxci_do_audio_callback(callNo, 0, IAXC_SOURCE_LOCAL, 1,
|
||||
call->encoder->format & IAXC_AUDIO_FORMAT_MASK,
|
||||
sizeof(outbuf) - outsize, outbuf);
|
||||
|
||||
if(iax_send_voice(call->session,format, outbuf,
|
||||
sizeof(outbuf) - outsize, samples-insize) == -1)
|
||||
{
|
||||
fprintf(stderr, "Failed to send voice! %s\n", iax_errstr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* decode encoded audio; return the number of bytes decoded
|
||||
* negative indicates error */
|
||||
int audio_decode_audio(struct iaxc_call * call, void * out, void * data, int len,
|
||||
int format, int * samples)
|
||||
{
|
||||
int insize = len;
|
||||
int outsize = *samples;
|
||||
|
||||
timeLastOutput = iax_tvnow();
|
||||
|
||||
if ( format == 0 )
|
||||
{
|
||||
fprintf(stderr, "audio_decode_audio: Format is zero (should't happen)!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* destroy decoder if it is incorrect type */
|
||||
if ( call->decoder && call->decoder->format != format )
|
||||
{
|
||||
call->decoder->destroy(call->decoder);
|
||||
call->decoder = NULL;
|
||||
}
|
||||
|
||||
/* create decoder if necessary */
|
||||
if ( !call->decoder )
|
||||
{
|
||||
call->decoder = create_codec(format);
|
||||
}
|
||||
|
||||
if ( !call->decoder )
|
||||
{
|
||||
fprintf(stderr, "ERROR: Codec could not be created: %d\n",
|
||||
format);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ( call->decoder->decode(call->decoder,
|
||||
&insize, (unsigned char *)data,
|
||||
&outsize, (short *)out) )
|
||||
{
|
||||
fprintf(stderr, "ERROR: decode error: %d\n", format);
|
||||
return -1;
|
||||
}
|
||||
|
||||
output_postprocess(out, *samples - outsize);
|
||||
|
||||
*samples = outsize;
|
||||
return len - insize;
|
||||
}
|
||||
|
||||
EXPORT int iaxc_get_filters(void)
|
||||
{
|
||||
return iaxci_filters;
|
||||
}
|
||||
|
||||
EXPORT void iaxc_set_filters(int filters)
|
||||
{
|
||||
iaxci_filters = filters;
|
||||
set_speex_filters();
|
||||
}
|
||||
|
||||
EXPORT void iaxc_set_silence_threshold(float thr)
|
||||
{
|
||||
iaxci_silence_threshold = thr;
|
||||
set_speex_filters();
|
||||
}
|
||||
|
33
utils/iaxclient/lib/audio_encode.h
Normal file
33
utils/iaxclient/lib/audio_encode.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* iaxclient: a cross-platform IAX softphone library
|
||||
*
|
||||
* Copyrights:
|
||||
* Copyright (C) 2003-2006, Horizon Wimba, Inc.
|
||||
* Copyright (C) 2007, Wimba, Inc.
|
||||
*
|
||||
* Contributors:
|
||||
* Steve Kann <stevek@stevek.com>
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU Lesser (Library) General Public License.
|
||||
*/
|
||||
|
||||
#ifndef _AUDIO_ENCODE_H
|
||||
#define _AUDIO_ENCODE_H
|
||||
|
||||
/* Minimum dB possible in the iaxclient world. This level
|
||||
* is intended to represent silence.
|
||||
*/
|
||||
#define AUDIO_ENCODE_SILENCE_DB -99.0f
|
||||
|
||||
struct iaxc_call;
|
||||
struct iax_event;
|
||||
|
||||
int audio_send_encoded_audio(struct iaxc_call * most_recent_answer, int callNo,
|
||||
void * data, int iEncodeType, int samples);
|
||||
|
||||
int audio_decode_audio(struct iaxc_call * p, void * out, void * data, int len,
|
||||
int iEncodeType, int * samples);
|
||||
|
||||
#endif
|
||||
|
130
utils/iaxclient/lib/audio_file.c
Normal file
130
utils/iaxclient/lib/audio_file.c
Normal file
|
@ -0,0 +1,130 @@
|
|||
/*
|
||||
* iaxclient_lib: An Inter-Asterisk eXchange communication library
|
||||
*
|
||||
* Module: audio_file
|
||||
* Purpose: Audio code to read/write to files
|
||||
* based on audio_portaudio, originally Developed by: Shawn Lawrence, Terrace Communications Inc.
|
||||
* Developed by: Steve Kann
|
||||
* Creation Date: October 30, 2003
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU Lesser (Library) General Public License
|
||||
*
|
||||
* IAX library Copyright (c) 2001 Linux Support Services
|
||||
* IAXlib is free software, distributed under the terms of
|
||||
* the GNU Lesser (Library) General Public License
|
||||
*
|
||||
* This library uses the PortAudio Portable Audio Library
|
||||
* For more information see: http://www.portaudio.com
|
||||
* PortAudio Copyright (c) 1999-2000 Ross Bencina and Phil Burk
|
||||
*
|
||||
*/
|
||||
|
||||
#include "iaxclient_lib.h"
|
||||
|
||||
typedef short SAMPLE;
|
||||
|
||||
static FILE *inFile=NULL, *outFile=NULL;
|
||||
|
||||
#define FRAMES_PER_BUFFER 80 /* 80 frames == 10ms */
|
||||
|
||||
|
||||
static int file_play_sound(struct iaxc_sound *inSound, int ring) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int file_stop_sound(int soundID) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int file_start (struct iaxc_audio_driver *d ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int file_stop (struct iaxc_audio_driver *d ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* not used
|
||||
static void file_shutdown_audio() {
|
||||
return;
|
||||
}
|
||||
*/
|
||||
|
||||
static int file_input(struct iaxc_audio_driver *d, void *samples, int *nSamples) {
|
||||
*nSamples = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int file_output(struct iaxc_audio_driver *d, void *samples, int nSamples) {
|
||||
|
||||
if(outFile) {
|
||||
fwrite(samples, sizeof(SAMPLE), nSamples, outFile);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int file_select_devices (struct iaxc_audio_driver *d, int input, int output, int ring) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int file_selected_devices (struct iaxc_audio_driver *d, int *input, int *output, int *ring) {
|
||||
*input = 0;
|
||||
*output = 0;
|
||||
*ring = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int file_destroy (struct iaxc_audio_driver *d )
|
||||
{
|
||||
/* TODO: something should happen here */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static float file_input_level_get(struct iaxc_audio_driver *d){
|
||||
return -1;
|
||||
}
|
||||
|
||||
static float file_output_level_get(struct iaxc_audio_driver *d){
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int file_input_level_set(struct iaxc_audio_driver *d, float level){
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int file_output_level_set(struct iaxc_audio_driver *d, float level){
|
||||
return -1;
|
||||
}
|
||||
|
||||
EXPORT int iaxc_set_files(FILE *input, FILE *output) {
|
||||
inFile = input;
|
||||
outFile = output;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* initialize audio driver */
|
||||
int file_initialize (struct iaxc_audio_driver *d , int sample_rate) {
|
||||
|
||||
if(sample_rate != 8000 ) return -1;
|
||||
|
||||
/* setup methods */
|
||||
d->initialize = file_initialize;
|
||||
d->destroy = file_destroy;
|
||||
d->select_devices = file_select_devices;
|
||||
d->selected_devices = file_selected_devices;
|
||||
d->start = file_start;
|
||||
d->stop = file_stop;
|
||||
d->output = file_output;
|
||||
d->input = file_input;
|
||||
d->input_level_get = file_input_level_get;
|
||||
d->input_level_set = file_input_level_set;
|
||||
d->output_level_get = file_output_level_get;
|
||||
d->output_level_set = file_output_level_set;
|
||||
d->play_sound = file_play_sound;
|
||||
d->stop_sound = file_stop_sound;
|
||||
|
||||
return 0;
|
||||
}
|
18
utils/iaxclient/lib/audio_file.h
Normal file
18
utils/iaxclient/lib/audio_file.h
Normal file
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* iaxclient: a cross-platform IAX softphone library
|
||||
*
|
||||
* Copyrights:
|
||||
* Copyright (C) 2003 HorizonLive.com, (c) 2004, Horizon Wimba, Inc.
|
||||
*
|
||||
* Contributors:
|
||||
* Steve Kann <stevek@stevek.com>
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU Lesser (Library) General Public License
|
||||
*/
|
||||
#ifndef _AUDIO_FILE_H
|
||||
#define _AUDIO_FILE_H
|
||||
|
||||
int file_initialize(struct iaxc_audio_driver *d , int sample_rate);
|
||||
|
||||
#endif
|
314
utils/iaxclient/lib/audio_openal.c
Normal file
314
utils/iaxclient/lib/audio_openal.c
Normal file
|
@ -0,0 +1,314 @@
|
|||
#include "iaxclient_lib.h"
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <OpenAL/al.h>
|
||||
#include <OpenAL/alc.h>
|
||||
#elif defined(OPENALSDK)
|
||||
#include <al.h>
|
||||
#include <alc.h>
|
||||
#else
|
||||
#include <AL/al.h>
|
||||
#include <AL/alc.h>
|
||||
#endif
|
||||
|
||||
struct openal_priv_data
|
||||
{
|
||||
int sample_rate;
|
||||
int num_buffers;
|
||||
int buffers_head;
|
||||
int buffers_tail;
|
||||
int buffers_free;
|
||||
ALuint* buffers;
|
||||
ALCcontext* out_ctx;
|
||||
ALuint source;
|
||||
ALCdevice* in_dev;
|
||||
double input_level;
|
||||
double output_level;
|
||||
};
|
||||
|
||||
static struct iaxc_audio_device device = {
|
||||
"default",
|
||||
IAXC_AD_INPUT | IAXC_AD_OUTPUT | IAXC_AD_RING | IAXC_AD_INPUT_DEFAULT | IAXC_AD_OUTPUT_DEFAULT | IAXC_AD_RING_DEFAULT,
|
||||
0
|
||||
};
|
||||
|
||||
static int openal_error(const char* function, int err)
|
||||
{
|
||||
fprintf(stderr, "OpenAl function %s failed with code %d\n", function, err);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int openal_input(struct iaxc_audio_driver *d, void *samples, int *nSamples)
|
||||
{
|
||||
int err;
|
||||
struct openal_priv_data* priv = (struct openal_priv_data*)(d->priv);
|
||||
|
||||
ALCint available;
|
||||
ALCsizei request;
|
||||
|
||||
alcGetIntegerv(priv->in_dev, ALC_CAPTURE_SAMPLES, sizeof(available), &available);
|
||||
/* do not return less data than caller wanted, iaxclient does not like it */
|
||||
request = (available < *nSamples) ? 0 : *nSamples;
|
||||
if (request > 0)
|
||||
{
|
||||
err = alcGetError(priv->in_dev);
|
||||
alcCaptureSamples(priv->in_dev, samples, request);
|
||||
err = alcGetError(priv->in_dev);
|
||||
if (err)
|
||||
{
|
||||
openal_error("alcCaptureSamples", err);
|
||||
*nSamples = 0;
|
||||
return 1;
|
||||
}
|
||||
// software mute, but keep data flowing for sync purposes
|
||||
if (priv->input_level == 0)
|
||||
{
|
||||
memset(samples, 0, 2 * request);
|
||||
}
|
||||
}
|
||||
*nSamples = request;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void openal_unqueue(struct openal_priv_data* priv)
|
||||
{
|
||||
int i;
|
||||
ALint err;
|
||||
ALint processed;
|
||||
|
||||
alGetSourcei(priv->source, AL_BUFFERS_PROCESSED, &processed);
|
||||
|
||||
#ifdef OPENAL_DEBUG
|
||||
{
|
||||
ALint queued;
|
||||
ALint state;
|
||||
|
||||
alGetSourcei(priv->source, AL_BUFFERS_QUEUED, &queued);
|
||||
alGetSourcei(priv->source, AL_SOURCE_STATE, &state);
|
||||
|
||||
fprintf(stderr, "free: %d processed: %d queued: %d head: %d tail: %d state: %d\n",
|
||||
priv->buffers_free, processed, queued, priv->buffers_head, priv->buffers_tail, state);
|
||||
}
|
||||
#endif
|
||||
|
||||
alGetError();
|
||||
for(i = 0; i < processed; i++)
|
||||
{
|
||||
alSourceUnqueueBuffers(priv->source, 1, priv->buffers + priv->buffers_tail);
|
||||
err = alGetError();
|
||||
if (err)
|
||||
{
|
||||
openal_error("alSourceUnqueueBuffers", err);
|
||||
break;
|
||||
}
|
||||
if (++priv->buffers_tail >= priv->num_buffers)
|
||||
{
|
||||
priv->buffers_tail = 0;
|
||||
}
|
||||
++priv->buffers_free;
|
||||
}
|
||||
}
|
||||
|
||||
int openal_output(struct iaxc_audio_driver *d, void *samples, int nSamples)
|
||||
{
|
||||
struct openal_priv_data* priv = (struct openal_priv_data*)(d->priv);
|
||||
|
||||
openal_unqueue(priv);
|
||||
/* If we run out of buffers, wait for an arbitrary number to become free */
|
||||
if (priv->buffers_free == 0)
|
||||
{
|
||||
while(priv->buffers_free < 4)
|
||||
{
|
||||
iaxc_millisleep(100);
|
||||
openal_unqueue(priv);
|
||||
}
|
||||
}
|
||||
|
||||
if (priv->buffers_free > 0)
|
||||
{
|
||||
ALuint buffer = priv->buffers[priv->buffers_head++];
|
||||
if (priv->buffers_head >= priv->num_buffers)
|
||||
{
|
||||
priv->buffers_head = 0;
|
||||
}
|
||||
|
||||
alBufferData(buffer, AL_FORMAT_MONO16, samples, nSamples * 2, priv->sample_rate);
|
||||
alSourceQueueBuffers(priv->source, 1, &buffer);
|
||||
--priv->buffers_free;
|
||||
|
||||
/* delay start of output until we have 2 buffers */
|
||||
if (priv->buffers_free == priv->num_buffers - 2)
|
||||
{
|
||||
ALint state;
|
||||
|
||||
alGetSourcei(priv->source, AL_SOURCE_STATE, &state);
|
||||
if (state != AL_PLAYING)
|
||||
{
|
||||
#ifdef OPENAL_DEBUG
|
||||
fprintf(stderr, "calling alSourcePlay\n");
|
||||
#endif
|
||||
alSourcePlay(priv->source);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "openal_output buffer overflow\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int openal_select_devices(struct iaxc_audio_driver *d, int input, int output, int ring)
|
||||
{
|
||||
return (input != 0 || output !=0 || ring != 0) ? -1 : 0;
|
||||
}
|
||||
|
||||
int openal_selected_devices(struct iaxc_audio_driver *d, int *input, int *output, int *ring)
|
||||
{
|
||||
*input = 0;
|
||||
*output = 0;
|
||||
*ring = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
Apparently iaxclient calls openal_start a gazillion times and doesn't call openal_stop.
|
||||
So let's just make them no-ops.
|
||||
*/
|
||||
int openal_start(struct iaxc_audio_driver *d)
|
||||
{
|
||||
int iret = 0;
|
||||
struct openal_priv_data* priv = (struct openal_priv_data*)(d->priv);
|
||||
if (priv) /* just to stop compiler noise */
|
||||
iret = 0;
|
||||
return iret;
|
||||
}
|
||||
|
||||
int openal_stop(struct iaxc_audio_driver *d)
|
||||
{
|
||||
int iret = 0;
|
||||
struct openal_priv_data* priv = (struct openal_priv_data*)(d->priv);
|
||||
if (priv) /* just to stop compiler noise */
|
||||
iret = 0;
|
||||
return iret;
|
||||
}
|
||||
|
||||
float openal_input_level_get(struct iaxc_audio_driver *d)
|
||||
{
|
||||
struct openal_priv_data* priv = (struct openal_priv_data*)(d->priv);
|
||||
|
||||
return (float)priv->input_level;
|
||||
}
|
||||
|
||||
float openal_output_level_get(struct iaxc_audio_driver *d)
|
||||
{
|
||||
struct openal_priv_data* priv = (struct openal_priv_data*)(d->priv);
|
||||
|
||||
return priv->output_level;
|
||||
}
|
||||
|
||||
int openal_input_level_set(struct iaxc_audio_driver *d, float level)
|
||||
{
|
||||
struct openal_priv_data* priv = (struct openal_priv_data*)(d->priv);
|
||||
priv->input_level = level;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int openal_output_level_set(struct iaxc_audio_driver *d, float level)
|
||||
{
|
||||
struct openal_priv_data* priv = (struct openal_priv_data*)(d->priv);
|
||||
priv->output_level = level;
|
||||
alSourcef(priv->source, AL_GAIN, level);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int openal_play_sound(struct iaxc_sound *s, int ring)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int openal_stop_sound(int id)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int openal_mic_boost_get(struct iaxc_audio_driver *d)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int openal_mic_boost_set(struct iaxc_audio_driver *d, int enable)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int openal_destroy(struct iaxc_audio_driver *d)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int openal_initialize(struct iaxc_audio_driver *d, int sample_rate)
|
||||
{
|
||||
struct openal_priv_data* priv = malloc(sizeof(struct openal_priv_data));
|
||||
int err = alGetError();
|
||||
d->priv = priv;
|
||||
|
||||
priv->out_ctx = alcGetCurrentContext();
|
||||
|
||||
if( priv->out_ctx == NULL ) { // FGCom standalone only
|
||||
ALCdevice* out_dev = alcOpenDevice(0);
|
||||
if (out_dev == 0) return openal_error("alcOpenDevice", alGetError());
|
||||
|
||||
priv->out_ctx = alcCreateContext(out_dev, 0);
|
||||
if (priv->out_ctx == 0) return openal_error("alcCreateContext", alGetError());
|
||||
}
|
||||
|
||||
alcMakeContextCurrent(priv->out_ctx);
|
||||
if ((err = alGetError())) return openal_error("alcMakeContextCurrent", err);
|
||||
|
||||
priv->sample_rate = sample_rate;
|
||||
priv->num_buffers = 20;
|
||||
priv->input_level = 1;
|
||||
priv->output_level = 1;
|
||||
priv->buffers_head = 0;
|
||||
priv->buffers_tail = 0;
|
||||
priv->buffers_free = priv->num_buffers;
|
||||
priv->buffers = (ALuint*)malloc(sizeof(ALuint) * priv->num_buffers);
|
||||
|
||||
alGenBuffers(priv->num_buffers, priv->buffers);
|
||||
if ((err = alGetError())) return openal_error("alGenBuffers", err);
|
||||
|
||||
alGenSources(1, &priv->source);
|
||||
if ((err = alGetError())) return openal_error("alGenSources", err);
|
||||
|
||||
priv->in_dev = alcCaptureOpenDevice(0, 8000, AL_FORMAT_MONO16, 800);
|
||||
if (!priv->in_dev) return openal_error("alcCaptureOpenDevice", 0);
|
||||
|
||||
alcCaptureStart(priv->in_dev);
|
||||
if ((err = alGetError())) return openal_error("alcCaptureStart", err);
|
||||
|
||||
d->initialize = openal_initialize;
|
||||
d->destroy = openal_destroy;
|
||||
d->select_devices = openal_select_devices;
|
||||
d->selected_devices = openal_selected_devices;
|
||||
d->start = openal_start;
|
||||
d->stop = openal_stop;
|
||||
d->output = openal_output;
|
||||
d->input = openal_input;
|
||||
d->input_level_get = openal_input_level_get;
|
||||
d->input_level_set = openal_input_level_set;
|
||||
d->output_level_get = openal_output_level_get;
|
||||
d->output_level_set = openal_output_level_set;
|
||||
d->mic_boost_get = openal_mic_boost_get;
|
||||
d->mic_boost_set = openal_mic_boost_set;
|
||||
d->play_sound = openal_play_sound;
|
||||
d->stop_sound = openal_stop_sound;
|
||||
d->nDevices = 1;
|
||||
d->devices = &device;
|
||||
|
||||
return 0;
|
||||
}
|
6
utils/iaxclient/lib/audio_openal.h
Normal file
6
utils/iaxclient/lib/audio_openal.h
Normal file
|
@ -0,0 +1,6 @@
|
|||
#ifndef _AUDIO_OPENAL_H
|
||||
#define _AUDIO_OPENAL_H
|
||||
|
||||
int openal_initialize();
|
||||
|
||||
#endif
|
1158
utils/iaxclient/lib/audio_portaudio.c
Normal file
1158
utils/iaxclient/lib/audio_portaudio.c
Normal file
File diff suppressed because it is too large
Load diff
27
utils/iaxclient/lib/audio_portaudio.h
Normal file
27
utils/iaxclient/lib/audio_portaudio.h
Normal file
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* iaxclient: a cross-platform IAX softphone library
|
||||
*
|
||||
* Copyrights:
|
||||
* Copyright (C) 2003-2006, Horizon Wimba, Inc.
|
||||
* Copyright (C) 2007, Wimba, Inc.
|
||||
*
|
||||
* Contributors:
|
||||
* Steve Kann <stevek@stevek.com>
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU Lesser (Library) General Public License.
|
||||
*/
|
||||
|
||||
#ifndef _AUDIO_PORTAUDIO_H
|
||||
#define _AUDIO_PORTAUDIO_H
|
||||
|
||||
#include "iaxclient_lib.h"
|
||||
|
||||
/* normal initialization */
|
||||
int pa_initialize (struct iaxc_audio_driver *d, int sr);
|
||||
|
||||
/* faster initialization which defers initialization of mixers and levels
|
||||
until the device is started */
|
||||
int pa_initialize_deferred (struct iaxc_audio_driver *d, int sr);
|
||||
|
||||
#endif
|
159
utils/iaxclient/lib/codec_alaw.c
Normal file
159
utils/iaxclient/lib/codec_alaw.c
Normal file
|
@ -0,0 +1,159 @@
|
|||
/*
|
||||
* iaxclient: a cross-platform IAX softphone library
|
||||
*
|
||||
* Copyrights:
|
||||
* Copyright (C) 2004 Cyril VELTER
|
||||
*
|
||||
* Contributors:
|
||||
* Cyril VELTER <cyril.velter@metadys.com>
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU Lesser (Library) General Public License.
|
||||
*/
|
||||
|
||||
#include "codec_alaw.h"
|
||||
#include "iaxclient_lib.h"
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#define INLINE __inline
|
||||
#else
|
||||
#define INLINE inline
|
||||
#endif
|
||||
|
||||
struct state {
|
||||
plc_state_t plc;
|
||||
};
|
||||
|
||||
static INLINE short int alawdecode (unsigned char alaw)
|
||||
{
|
||||
int value;
|
||||
int segment;
|
||||
|
||||
/* Mask value */
|
||||
alaw ^= 0x55;
|
||||
|
||||
/* Extract and scale value */
|
||||
value = (alaw & 0x0f) << 4;
|
||||
|
||||
/* Extract segment number */
|
||||
segment = (alaw & 0x70) >> 4;
|
||||
|
||||
/* Compute value */
|
||||
switch (segment) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
value += 0x100;
|
||||
break;
|
||||
default:
|
||||
value += 0x100;
|
||||
value <<= segment - 1;
|
||||
}
|
||||
|
||||
/* Extract sign */
|
||||
return (alaw & 0x80) ? value : -value;
|
||||
}
|
||||
|
||||
static INLINE unsigned char alawencode (short int linear)
|
||||
{
|
||||
int mask = 0x55;
|
||||
int segment;
|
||||
unsigned char alaw;
|
||||
|
||||
static int segments[8] = {0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF};
|
||||
|
||||
if (linear >= 0)
|
||||
{
|
||||
/* Sign (7th) bit = 1 */
|
||||
mask |= 0x80;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Sign (7th) bit = 0 */
|
||||
linear = -linear;
|
||||
}
|
||||
|
||||
/* Find the segment */
|
||||
for (segment = 0;segment < 8;segment++)
|
||||
if (linear <= segments[segment])
|
||||
break;
|
||||
|
||||
/* Combine the sign, segment, and quantization bits. */
|
||||
|
||||
if (segment < 8)
|
||||
{
|
||||
if (segment < 2)
|
||||
alaw = (linear >> 4) & 0x0F;
|
||||
else
|
||||
alaw = (linear >> (segment + 3)) & 0x0F;
|
||||
|
||||
return ((alaw | (segment << 4)) ^ mask);
|
||||
}
|
||||
else
|
||||
/* out of range, return maximum value. */
|
||||
return (0x7F ^ mask);
|
||||
}
|
||||
|
||||
static int decode ( struct iaxc_audio_codec *c,
|
||||
int *inlen, unsigned char *in, int *outlen, short *out ) {
|
||||
struct state *state = (struct state *)(c->decstate);
|
||||
short *orig_out = out;
|
||||
short sample;
|
||||
|
||||
|
||||
if(*inlen == 0) {
|
||||
int interp_len = 160;
|
||||
if(*outlen < interp_len) interp_len = *outlen;
|
||||
plc_fillin(&state->plc,out,interp_len);
|
||||
*outlen -= interp_len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
while ((*inlen > 0) && (*outlen > 0)) {
|
||||
sample = alawdecode((unsigned char)*(in++));
|
||||
*(out++) = sample;
|
||||
(*inlen)--; (*outlen)--;
|
||||
}
|
||||
plc_rx(&state->plc, orig_out, (int)(out - orig_out));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int encode ( struct iaxc_audio_codec *c,
|
||||
int *inlen, short *in, int *outlen, unsigned char *out ) {
|
||||
|
||||
while ((*inlen > 0) && (*outlen > 0)) {
|
||||
*(out++) = alawencode(*(in++));
|
||||
(*inlen)--; (*outlen)--;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void destroy ( struct iaxc_audio_codec *c) {
|
||||
free(c);
|
||||
}
|
||||
|
||||
struct iaxc_audio_codec *codec_audio_alaw_new() {
|
||||
|
||||
struct iaxc_audio_codec *c = (struct iaxc_audio_codec *)calloc(1, sizeof(struct iaxc_audio_codec));
|
||||
|
||||
if(!c) return c;
|
||||
|
||||
strcpy(c->name,"alaw");
|
||||
c->format = IAXC_FORMAT_ALAW;
|
||||
c->encode = encode;
|
||||
c->decode = decode;
|
||||
c->destroy = destroy;
|
||||
|
||||
/* really, we can use less, but don't want to */
|
||||
c->minimum_frame_size = 160;
|
||||
|
||||
/* decoder state, used for interpolation */
|
||||
c->decstate = calloc(sizeof(struct state),1);
|
||||
plc_init(&((struct state *)c->decstate)->plc);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
14
utils/iaxclient/lib/codec_alaw.h
Normal file
14
utils/iaxclient/lib/codec_alaw.h
Normal file
|
@ -0,0 +1,14 @@
|
|||
/*
|
||||
* iaxclient: a cross-platform IAX softphone library
|
||||
*
|
||||
* Copyrights:
|
||||
* Copyright (C) 2004 Cyril VELTER
|
||||
*
|
||||
* Contributors:
|
||||
* Cyril VELTER <cyril.velter@metadys.com>
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU Lesser (Library) General Public License.
|
||||
*/
|
||||
|
||||
struct iaxc_audio_codec *codec_audio_alaw_new();
|
748
utils/iaxclient/lib/codec_ffmpeg.c
Normal file
748
utils/iaxclient/lib/codec_ffmpeg.c
Normal file
|
@ -0,0 +1,748 @@
|
|||
/*
|
||||
* iaxclient: a cross-platform IAX softphone library
|
||||
*
|
||||
* Copyrights:
|
||||
* Copyright (C) 2003-2006, Horizon Wimba, Inc.
|
||||
* Copyright (C) 2007, Wimba, Inc.
|
||||
*
|
||||
* Contributors:
|
||||
* Steve Kann <stevek@stevek.com>
|
||||
* Peter Grayson <jpgrayson@gmail.com>
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU Lesser (Library) General Public License.
|
||||
*
|
||||
* A video codec using the ffmpeg library.
|
||||
*
|
||||
* TODO: this code still uses its own slicing mechanism
|
||||
* It should be converted to use the API provided in slice.[ch]
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "codec_ffmpeg.h"
|
||||
#include "iaxclient_lib.h"
|
||||
|
||||
#ifdef WIN32
|
||||
#include "libavcodec/avcodec.h"
|
||||
#else
|
||||
#include <ffmpeg/avcodec.h>
|
||||
#endif
|
||||
|
||||
struct slice_header_t
|
||||
{
|
||||
unsigned char version;
|
||||
unsigned short source_id;
|
||||
unsigned char frame_index;
|
||||
unsigned char slice_index;
|
||||
unsigned char num_slices;
|
||||
};
|
||||
|
||||
struct encoder_ctx
|
||||
{
|
||||
AVCodecContext * avctx;
|
||||
AVFrame * picture;
|
||||
|
||||
struct slice_header_t slice_header;
|
||||
|
||||
unsigned char *frame_buf;
|
||||
int frame_buf_len;
|
||||
};
|
||||
|
||||
struct decoder_ctx
|
||||
{
|
||||
AVCodecContext * avctx;
|
||||
AVFrame * picture;
|
||||
|
||||
struct slice_header_t slice_header;
|
||||
int frame_size;
|
||||
|
||||
unsigned char * frame_buf;
|
||||
int frame_buf_len;
|
||||
};
|
||||
|
||||
static struct slice_set_t * g_slice_set = 0;
|
||||
|
||||
static enum CodecID map_iaxc_codec_to_avcodec(int format)
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
case IAXC_FORMAT_H261:
|
||||
return CODEC_ID_H261;
|
||||
|
||||
case IAXC_FORMAT_H263:
|
||||
return CODEC_ID_H263;
|
||||
|
||||
case IAXC_FORMAT_H263_PLUS:
|
||||
return CODEC_ID_H263P;
|
||||
|
||||
case IAXC_FORMAT_MPEG4:
|
||||
return CODEC_ID_MPEG4;
|
||||
|
||||
case IAXC_FORMAT_H264:
|
||||
return CODEC_ID_H264;
|
||||
|
||||
case IAXC_FORMAT_THEORA:
|
||||
return CODEC_ID_THEORA;
|
||||
|
||||
default:
|
||||
return CODEC_ID_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
static void destroy(struct iaxc_video_codec *c)
|
||||
{
|
||||
if (c)
|
||||
{
|
||||
struct encoder_ctx *e = (struct encoder_ctx *) c->encstate;
|
||||
struct decoder_ctx *d = (struct decoder_ctx *) c->decstate;
|
||||
|
||||
if (e)
|
||||
{
|
||||
av_freep(&e->avctx);
|
||||
av_freep(&e->picture);
|
||||
if (e->frame_buf)
|
||||
free(e->frame_buf);
|
||||
free(e);
|
||||
}
|
||||
|
||||
if (d)
|
||||
{
|
||||
av_freep(&d->avctx);
|
||||
av_freep(&d->picture);
|
||||
if (d->frame_buf)
|
||||
free(d->frame_buf);
|
||||
free(d);
|
||||
}
|
||||
|
||||
free(c);
|
||||
}
|
||||
}
|
||||
|
||||
static void reset_decoder_frame_state(struct decoder_ctx * d)
|
||||
{
|
||||
memset(d->frame_buf, 0, d->frame_buf_len);
|
||||
d->frame_size = 0;
|
||||
d->slice_header.slice_index = 0;
|
||||
}
|
||||
|
||||
static int frame_to_frame_xlate(AVCodecContext * avctx, AVFrame * picture,
|
||||
int * outlen, char * out)
|
||||
{
|
||||
int line;
|
||||
|
||||
*outlen = avctx->width * avctx->height * 6 / 4;
|
||||
|
||||
for ( line = 0; line < avctx->height / 2; ++line )
|
||||
{
|
||||
/* y even */
|
||||
memcpy(out + avctx->width * (2 * line + 0),
|
||||
picture->data[0] + (2 * line + 0) * picture->linesize[0],
|
||||
avctx->width);
|
||||
|
||||
/* y odd */
|
||||
memcpy(out + avctx->width * (2 * line + 1),
|
||||
picture->data[0] + (2 * line + 1) * picture->linesize[0],
|
||||
avctx->width);
|
||||
|
||||
/* u + v */
|
||||
memcpy(out + avctx->width * avctx->height
|
||||
+ line * avctx->width / 2,
|
||||
picture->data[1] + line * picture->linesize[1],
|
||||
avctx->width / 2);
|
||||
|
||||
memcpy(out + avctx->width * avctx->height * 5 / 4
|
||||
+ line * avctx->width / 2,
|
||||
picture->data[2] + line * picture->linesize[2],
|
||||
avctx->width / 2);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pass_frame_to_decoder(AVCodecContext * avctx, AVFrame * picture,
|
||||
int inlen, unsigned char * in, int * outlen, char * out)
|
||||
{
|
||||
int bytes_decoded;
|
||||
int got_picture;
|
||||
|
||||
bytes_decoded = avcodec_decode_video(avctx, picture, &got_picture,
|
||||
in, inlen);
|
||||
|
||||
if ( bytes_decoded != inlen )
|
||||
{
|
||||
fprintf(stderr,
|
||||
"codec_ffmpeg: decode: failed to decode whole frame %d / %d\n",
|
||||
bytes_decoded, inlen);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ( !got_picture )
|
||||
{
|
||||
fprintf(stderr,
|
||||
"codec_ffmpeg: decode: failed to get picture\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
frame_to_frame_xlate(avctx, picture, outlen, out);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char *parse_slice_header(char * in, struct slice_header_t * slice_header)
|
||||
{
|
||||
slice_header->version = in[0];
|
||||
slice_header->source_id = (in[1] << 8) | in[2];
|
||||
slice_header->frame_index = in[3];
|
||||
slice_header->slice_index = in[4];
|
||||
slice_header->num_slices = in[5];
|
||||
|
||||
if ( slice_header->version != 0 )
|
||||
{
|
||||
fprintf(stderr,
|
||||
"codec_ffmpeg: decode: unknown slice header version %d\n",
|
||||
slice_header->version);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return in + 6;
|
||||
}
|
||||
|
||||
static int decode_iaxc_slice(struct iaxc_video_codec * c, int inlen,
|
||||
char * in, int * outlen, char * out)
|
||||
{
|
||||
struct decoder_ctx *d = (struct decoder_ctx *) c->decstate;
|
||||
struct slice_header_t * sh_saved = &d->slice_header;
|
||||
struct slice_header_t sh_this;
|
||||
char * inp;
|
||||
int ret;
|
||||
|
||||
inp = parse_slice_header(in, &sh_this);
|
||||
|
||||
if ( !inp )
|
||||
return -1;
|
||||
|
||||
inlen -= inp - in;
|
||||
|
||||
if ( sh_this.source_id == sh_saved->source_id )
|
||||
{
|
||||
unsigned char frame_delta;
|
||||
|
||||
frame_delta = sh_this.frame_index - sh_saved->frame_index;
|
||||
|
||||
if ( frame_delta > 20 )
|
||||
{
|
||||
/* This is an old slice. It's too late, we ignore it. */
|
||||
return 1;
|
||||
}
|
||||
else if ( frame_delta > 0 )
|
||||
{
|
||||
/* This slice belongs to a future frame */
|
||||
if ( sh_saved->slice_index > 0 )
|
||||
{
|
||||
/* We have received slices for a previous
|
||||
* frame (e.g. the one we were previously
|
||||
* working on), so we go ahead and send this
|
||||
* partial frame to the decoder and get setup
|
||||
* for the new frame.
|
||||
*/
|
||||
|
||||
ret = pass_frame_to_decoder(d->avctx, d->picture,
|
||||
d->frame_size, d->frame_buf,
|
||||
outlen, out);
|
||||
|
||||
reset_decoder_frame_state(d);
|
||||
|
||||
if ( ret )
|
||||
return -1;
|
||||
}
|
||||
|
||||
sh_saved->frame_index = sh_this.frame_index;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sh_saved->source_id = sh_this.source_id;
|
||||
sh_saved->frame_index = sh_this.frame_index;
|
||||
sh_saved->slice_index = 0;
|
||||
d->frame_size = 0;
|
||||
}
|
||||
|
||||
if ( c->fragsize * sh_this.slice_index + inlen > d->frame_buf_len )
|
||||
{
|
||||
fprintf(stderr,
|
||||
"codec_ffmpeg: decode: slice overflows decoder frame buffer\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(d->frame_buf + c->fragsize * sh_this.slice_index,
|
||||
inp, inlen);
|
||||
sh_saved->slice_index++;
|
||||
d->frame_size = c->fragsize * sh_this.slice_index + inlen;
|
||||
|
||||
if ( sh_saved->slice_index < sh_this.num_slices )
|
||||
{
|
||||
/* Do not decode yet, there are more slices coming for
|
||||
* this frame.
|
||||
*/
|
||||
return 1;
|
||||
}
|
||||
|
||||
ret = pass_frame_to_decoder(d->avctx, d->picture, d->frame_size,
|
||||
d->frame_buf, outlen, out);
|
||||
|
||||
reset_decoder_frame_state(d);
|
||||
|
||||
if ( ret )
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int decode_rtp_slice(struct iaxc_video_codec * c,
|
||||
int inlen, char * in, int * outlen, char * out)
|
||||
{
|
||||
struct decoder_ctx *d = (struct decoder_ctx *) c->decstate;
|
||||
int ret = 1;
|
||||
|
||||
while ( inlen )
|
||||
{
|
||||
int bytes_decoded;
|
||||
int got_picture;
|
||||
|
||||
bytes_decoded = avcodec_decode_video(d->avctx, d->picture,
|
||||
&got_picture, (unsigned char *)in, inlen);
|
||||
|
||||
if ( bytes_decoded < 0 )
|
||||
{
|
||||
fprintf(stderr,
|
||||
"codec_ffmpeg: decode: error decoding frame\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
inlen -= bytes_decoded;
|
||||
in += bytes_decoded;
|
||||
|
||||
if ( got_picture && ret == 0)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"codec_ffmpeg: decode: unexpected second frame\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ( got_picture )
|
||||
{
|
||||
frame_to_frame_xlate(d->avctx, d->picture, outlen, out);
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void slice_encoded_frame(struct slice_header_t * sh,
|
||||
struct slice_set_t * slice_set,
|
||||
unsigned char * in, int inlen, int fragsize)
|
||||
{
|
||||
sh->num_slices = slice_set->num_slices = (inlen - 1) / fragsize + 1;
|
||||
|
||||
for (sh->slice_index = 0; sh->slice_index < sh->num_slices;
|
||||
++sh->slice_index)
|
||||
{
|
||||
int slice_size = (sh->slice_index == sh->num_slices - 1) ?
|
||||
inlen % fragsize : fragsize;
|
||||
|
||||
slice_set->size[sh->slice_index] = slice_size + 6;
|
||||
slice_set->data[sh->slice_index][0] = sh->version;
|
||||
slice_set->data[sh->slice_index][1] = sh->source_id >> 8;
|
||||
slice_set->data[sh->slice_index][2] = sh->source_id & 0xff;
|
||||
slice_set->data[sh->slice_index][3] = sh->frame_index;
|
||||
slice_set->data[sh->slice_index][4] = sh->slice_index;
|
||||
slice_set->data[sh->slice_index][5] = sh->num_slices;
|
||||
|
||||
memcpy(&slice_set->data[sh->slice_index][6], in, slice_size);
|
||||
|
||||
in += slice_size;
|
||||
}
|
||||
|
||||
sh->frame_index++;
|
||||
}
|
||||
|
||||
static int encode(struct iaxc_video_codec *c,
|
||||
int inlen, char * in, struct slice_set_t * slice_set)
|
||||
{
|
||||
struct encoder_ctx *e = (struct encoder_ctx *) c->encstate;
|
||||
int encoded_size;
|
||||
|
||||
avcodec_get_frame_defaults(e->picture);
|
||||
|
||||
e->picture->data[0] = (unsigned char *)in;
|
||||
e->picture->data[1] = (unsigned char *)in
|
||||
+ e->avctx->width * e->avctx->height;
|
||||
e->picture->data[2] = (unsigned char *)in
|
||||
+ e->avctx->width * e->avctx->height * 5 / 4;
|
||||
|
||||
e->picture->linesize[0] = e->avctx->width;
|
||||
e->picture->linesize[1] = e->avctx->width / 2;
|
||||
e->picture->linesize[2] = e->avctx->width / 2;
|
||||
|
||||
/* TODO: investigate setting a real pts value */
|
||||
e->picture->pts = AV_NOPTS_VALUE;
|
||||
|
||||
/* TODO: investigate quality */
|
||||
e->picture->quality = 10;
|
||||
|
||||
g_slice_set = slice_set;
|
||||
slice_set->num_slices = 0;
|
||||
|
||||
encoded_size = avcodec_encode_video(e->avctx,
|
||||
e->frame_buf, e->frame_buf_len, e->picture);
|
||||
|
||||
if (!encoded_size)
|
||||
{
|
||||
fprintf(stderr, "codec_ffmpeg: encode failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
slice_set->key_frame = e->avctx->coded_frame->key_frame;
|
||||
|
||||
/* This is paranoia, of course. */
|
||||
g_slice_set = 0;
|
||||
|
||||
/* We are in one of two modes here.
|
||||
*
|
||||
* The first possibility is that the codec supports rtp
|
||||
* packetization. In this case, the slice_set has already been
|
||||
* filled via encode_rtp_callback() calls made during the call
|
||||
* to avcodec_encode_video().
|
||||
*
|
||||
* The second possibility is that we have one big encoded frame
|
||||
* that we need to slice-up ourselves.
|
||||
*/
|
||||
|
||||
if (!e->avctx->rtp_payload_size)
|
||||
slice_encoded_frame(&e->slice_header, slice_set,
|
||||
e->frame_buf, encoded_size, c->fragsize);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void encode_rtp_callback(struct AVCodecContext *avctx, void *data, int size,
|
||||
int mb_nb)
|
||||
{
|
||||
memcpy(&g_slice_set->data[g_slice_set->num_slices], data, size);
|
||||
g_slice_set->size[g_slice_set->num_slices] = size;
|
||||
g_slice_set->num_slices++;
|
||||
}
|
||||
|
||||
struct iaxc_video_codec *codec_video_ffmpeg_new(int format, int w, int h,
|
||||
int framerate, int bitrate,
|
||||
int fragsize)
|
||||
{
|
||||
struct encoder_ctx *e;
|
||||
struct decoder_ctx *d;
|
||||
AVCodec *codec;
|
||||
int ff_enc_id, ff_dec_id;
|
||||
char *name;
|
||||
|
||||
struct iaxc_video_codec *c = calloc(sizeof(struct iaxc_video_codec), 1);
|
||||
|
||||
if (!c)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"codec_ffmpeg: failed to allocate video context\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
avcodec_init();
|
||||
avcodec_register_all();
|
||||
|
||||
c->format = format;
|
||||
c->width = w;
|
||||
c->height = h;
|
||||
c->framerate = framerate;
|
||||
c->bitrate = bitrate;
|
||||
/* TODO: Is a fragsize of zero valid? If so, there's a divide
|
||||
* by zero error to contend with.
|
||||
*/
|
||||
c->fragsize = fragsize;
|
||||
|
||||
c->encode = encode;
|
||||
c->decode = decode_iaxc_slice;
|
||||
c->destroy = destroy;
|
||||
|
||||
c->encstate = calloc(sizeof(struct encoder_ctx), 1);
|
||||
if (!c->encstate)
|
||||
goto bail;
|
||||
e = c->encstate;
|
||||
e->avctx = avcodec_alloc_context();
|
||||
if (!e->avctx)
|
||||
goto bail;
|
||||
e->picture = avcodec_alloc_frame();
|
||||
if (!e->picture)
|
||||
goto bail;
|
||||
/* The idea here is that the encoded frame that will land in this
|
||||
* buffer will be no larger than the size of an uncompressed 32-bit
|
||||
* rgb frame.
|
||||
*
|
||||
* TODO: Is this assumption really valid?
|
||||
*/
|
||||
e->frame_buf_len = w * h * 4;
|
||||
e->frame_buf = malloc(e->frame_buf_len);
|
||||
if (!e->frame_buf)
|
||||
goto bail;
|
||||
|
||||
c->decstate = calloc(sizeof(struct decoder_ctx), 1);
|
||||
if (!c->decstate)
|
||||
goto bail;
|
||||
d = c->decstate;
|
||||
d->avctx = avcodec_alloc_context();
|
||||
if (!d->avctx)
|
||||
goto bail;
|
||||
d->picture = avcodec_alloc_frame();
|
||||
if (!d->picture)
|
||||
goto bail;
|
||||
d->frame_buf_len = e->frame_buf_len;
|
||||
d->frame_buf = malloc(d->frame_buf_len);
|
||||
if (!d->frame_buf)
|
||||
goto bail;
|
||||
|
||||
e->slice_header.version = 0;
|
||||
srandom(time(0));
|
||||
e->slice_header.source_id = random() & 0xffff;
|
||||
|
||||
e->avctx->time_base.num = 1;
|
||||
e->avctx->time_base.den = framerate;
|
||||
|
||||
e->avctx->width = w;
|
||||
e->avctx->height = h;
|
||||
|
||||
e->avctx->bit_rate = bitrate;
|
||||
|
||||
/* This determines how often i-frames are sent */
|
||||
e->avctx->gop_size = framerate * 3;
|
||||
e->avctx->pix_fmt = PIX_FMT_YUV420P;
|
||||
e->avctx->has_b_frames = 0;
|
||||
|
||||
e->avctx->mb_qmin = e->avctx->qmin = 10;
|
||||
e->avctx->mb_qmax = e->avctx->qmax = 10;
|
||||
|
||||
e->avctx->lmin = 2 * FF_QP2LAMBDA;
|
||||
e->avctx->lmax = 10 * FF_QP2LAMBDA;
|
||||
e->avctx->global_quality = FF_QP2LAMBDA * 2;
|
||||
e->avctx->qblur = 0.5;
|
||||
e->avctx->global_quality = 10;
|
||||
|
||||
e->avctx->flags |= CODEC_FLAG_PSNR;
|
||||
e->avctx->flags |= CODEC_FLAG_QSCALE;
|
||||
|
||||
e->avctx->mb_decision = FF_MB_DECISION_SIMPLE;
|
||||
|
||||
ff_enc_id = ff_dec_id = map_iaxc_codec_to_avcodec(format);
|
||||
|
||||
/* Note, when fragsize is used (non-zero) ffmpeg will use a "best
|
||||
* effort" strategy: the fragment size will be fragsize +/- 20%
|
||||
*/
|
||||
|
||||
switch (format)
|
||||
{
|
||||
|
||||
case IAXC_FORMAT_H261:
|
||||
/* TODO: H261 only works with specific resolutions. */
|
||||
name = "H.261";
|
||||
break;
|
||||
|
||||
case IAXC_FORMAT_H263:
|
||||
/* TODO: H263 only works with specific resolutions. */
|
||||
name = "H.263";
|
||||
e->avctx->flags |= CODEC_FLAG_AC_PRED;
|
||||
if (fragsize)
|
||||
{
|
||||
c->decode = decode_rtp_slice;
|
||||
e->avctx->rtp_payload_size = fragsize;
|
||||
e->avctx->flags |=
|
||||
CODEC_FLAG_TRUNCATED | CODEC_FLAG2_STRICT_GOP;
|
||||
e->avctx->rtp_callback = encode_rtp_callback;
|
||||
d->avctx->flags |= CODEC_FLAG_TRUNCATED;
|
||||
}
|
||||
break;
|
||||
|
||||
case IAXC_FORMAT_H263_PLUS:
|
||||
/* Although the encoder is CODEC_ID_H263P, the decoder
|
||||
* is the regular h.263, so we handle this special case
|
||||
* here.
|
||||
*/
|
||||
ff_dec_id = CODEC_ID_H263;
|
||||
name = "H.263+";
|
||||
e->avctx->flags |= CODEC_FLAG_AC_PRED;
|
||||
if (fragsize)
|
||||
{
|
||||
c->decode = decode_rtp_slice;
|
||||
e->avctx->rtp_payload_size = fragsize;
|
||||
e->avctx->flags |=
|
||||
CODEC_FLAG_TRUNCATED |
|
||||
CODEC_FLAG_H263P_SLICE_STRUCT |
|
||||
CODEC_FLAG2_STRICT_GOP |
|
||||
CODEC_FLAG2_LOCAL_HEADER;
|
||||
e->avctx->rtp_callback = encode_rtp_callback;
|
||||
d->avctx->flags |= CODEC_FLAG_TRUNCATED;
|
||||
}
|
||||
break;
|
||||
|
||||
case IAXC_FORMAT_MPEG4:
|
||||
name = "MPEG4";
|
||||
c->decode = decode_rtp_slice;
|
||||
e->avctx->rtp_payload_size = fragsize;
|
||||
e->avctx->rtp_callback = encode_rtp_callback;
|
||||
e->avctx->flags |=
|
||||
CODEC_FLAG_TRUNCATED |
|
||||
CODEC_FLAG_H263P_SLICE_STRUCT |
|
||||
CODEC_FLAG2_STRICT_GOP |
|
||||
CODEC_FLAG2_LOCAL_HEADER;
|
||||
|
||||
d->avctx->flags |= CODEC_FLAG_TRUNCATED;
|
||||
break;
|
||||
|
||||
case IAXC_FORMAT_H264:
|
||||
name = "H.264";
|
||||
|
||||
/*
|
||||
* Encoder flags
|
||||
*/
|
||||
|
||||
/* Headers are not repeated */
|
||||
/* e->avctx->flags |= CODEC_FLAG_GLOBAL_HEADER; */
|
||||
|
||||
/* Slower, less blocky */
|
||||
/* e->avctx->flags |= CODEC_FLAG_LOOP_FILTER; */
|
||||
|
||||
e->avctx->flags |= CODEC_FLAG_PASS1;
|
||||
/* e->avctx->flags |= CODEC_FLAG_PASS2; */
|
||||
|
||||
/* Compute psnr values at encode-time (avctx->error[]) */
|
||||
/* e->avctx->flags |= CODEC_FLAG_PSNR; */
|
||||
|
||||
/* e->avctx->flags2 |= CODEC_FLAG2_8X8DCT; */
|
||||
|
||||
/* Access Unit Delimiters */
|
||||
e->avctx->flags2 |= CODEC_FLAG2_AUD;
|
||||
|
||||
/* Allow b-frames to be used as reference */
|
||||
/* e->avctx->flags2 |= CODEC_FLAG2_BPYRAMID; */
|
||||
|
||||
/* b-frame rate distortion optimization */
|
||||
/* e->avctx->flags2 |= CODEC_FLAG2_BRDO; */
|
||||
|
||||
/* e->avctx->flags2 |= CODEC_FLAG2_FASTPSKIP; */
|
||||
|
||||
/* Multiple references per partition */
|
||||
/* e->avctx->flags2 |= CODEC_FLAG2_MIXED_REFS; */
|
||||
|
||||
/* Weighted biprediction for b-frames */
|
||||
/* e->avctx->flags2 |= CODEC_FLAG2_WPRED; */
|
||||
|
||||
/*
|
||||
* Decoder flags
|
||||
*/
|
||||
|
||||
/* Do not draw edges */
|
||||
/* d->avctx->flags |= CODEC_FLAG_EMU_EDGE; */
|
||||
|
||||
/* Decode grayscale only */
|
||||
/* d->avctx->flags |= CODEC_FLAG_GRAY; */
|
||||
|
||||
/* d->avctx->flags |= CODEC_FLAG_LOW_DELAY; */
|
||||
|
||||
/* Allow input bitstream to be randomly truncated */
|
||||
/* d->avctx->flags |= CODEC_FLAG_TRUNCATED; */
|
||||
|
||||
/* Allow out-of-spec speed tricks */
|
||||
/* d->avctx->flags2 |= CODEC_FLAG2_FAST; */
|
||||
break;
|
||||
|
||||
case IAXC_FORMAT_THEORA:
|
||||
/* TODO: ffmpeg only has a theora decoder. Until it has
|
||||
* an encoder also, we cannot use ffmpeg for theora.
|
||||
*/
|
||||
name = "Theora";
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "codec_ffmpeg: unsupported format (0x%08x)\n",
|
||||
format);
|
||||
goto bail;
|
||||
}
|
||||
|
||||
strcpy(c->name, "ffmpeg-");
|
||||
strncat(c->name, name, sizeof(c->name));
|
||||
|
||||
/* Get the codecs */
|
||||
codec = avcodec_find_encoder(ff_enc_id);
|
||||
if (!codec)
|
||||
{
|
||||
iaxci_usermsg(IAXC_TEXT_TYPE_ERROR,
|
||||
"codec_ffmpeg: cannot find encoder %d\n",
|
||||
ff_enc_id);
|
||||
goto bail;
|
||||
}
|
||||
|
||||
if (avcodec_open(e->avctx, codec))
|
||||
{
|
||||
iaxci_usermsg(IAXC_TEXT_TYPE_ERROR,
|
||||
"codec_ffmpeg: cannot open encoder %s\n", name);
|
||||
goto bail;
|
||||
}
|
||||
|
||||
codec = avcodec_find_decoder(ff_dec_id);
|
||||
if (!codec)
|
||||
{
|
||||
iaxci_usermsg(IAXC_TEXT_TYPE_ERROR,
|
||||
"codec_ffmpeg: cannot find decoder %d\n",
|
||||
ff_dec_id);
|
||||
goto bail;
|
||||
}
|
||||
if (avcodec_open(d->avctx, codec))
|
||||
{
|
||||
iaxci_usermsg(IAXC_TEXT_TYPE_ERROR,
|
||||
"codec_ffmpeg: cannot open decoder %s\n", name);
|
||||
goto bail;
|
||||
}
|
||||
|
||||
{
|
||||
enum PixelFormat fmts[] = { PIX_FMT_YUV420P, -1 };
|
||||
if (d->avctx->get_format(d->avctx, fmts) != PIX_FMT_YUV420P)
|
||||
{
|
||||
iaxci_usermsg(IAXC_TEXT_TYPE_ERROR,
|
||||
"codec_ffmpeg: cannot set decode format to YUV420P\n");
|
||||
goto bail;
|
||||
}
|
||||
}
|
||||
|
||||
return c;
|
||||
|
||||
bail:
|
||||
destroy(c);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int codec_video_ffmpeg_check_codec(int format)
|
||||
{
|
||||
AVCodec *codec;
|
||||
enum CodecID codec_id;
|
||||
|
||||
/* These functions are idempotent, so it is okay that we
|
||||
* may call them elsewhere at a different time.
|
||||
*/
|
||||
avcodec_init();
|
||||
avcodec_register_all();
|
||||
|
||||
codec_id = map_iaxc_codec_to_avcodec(format);
|
||||
|
||||
if (codec_id == CODEC_ID_NONE)
|
||||
return 0;
|
||||
|
||||
codec = avcodec_find_encoder(codec_id);
|
||||
|
||||
return codec ? 1 : 0;
|
||||
}
|
||||
|
20
utils/iaxclient/lib/codec_ffmpeg.h
Normal file
20
utils/iaxclient/lib/codec_ffmpeg.h
Normal file
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* iaxclient: a cross-platform IAX softphone library
|
||||
*
|
||||
* Copyrights:
|
||||
* Copyright (C) 2003-2006, Horizon Wimba, Inc.
|
||||
* Copyright (C) 2007, Wimba, Inc.
|
||||
*
|
||||
* Contributors:
|
||||
* Steve Kann <stevek@stevek.com>
|
||||
* Peter Grayson <jpgrayson@gmail.com>
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU Lesser (Library) General Public License.
|
||||
*
|
||||
* A video codec using the ffmpeg library.
|
||||
*/
|
||||
|
||||
struct iaxc_video_codec *codec_video_ffmpeg_new(int format, int w, int h, int framerate, int bitrate, int fragsize);
|
||||
|
||||
int codec_video_ffmpeg_check_codec(int format);
|
127
utils/iaxclient/lib/codec_gsm.c
Normal file
127
utils/iaxclient/lib/codec_gsm.c
Normal file
|
@ -0,0 +1,127 @@
|
|||
/*
|
||||
* iaxclient: a cross-platform IAX softphone library
|
||||
*
|
||||
* Copyrights:
|
||||
* Copyright (C) 2003-2006, Horizon Wimba, Inc.
|
||||
* Copyright (C) 2007, Wimba, Inc.
|
||||
*
|
||||
* Contributors:
|
||||
* Steve Kann <stevek@stevek.com>
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU Lesser (Library) General Public License.
|
||||
*/
|
||||
|
||||
#include "codec_gsm.h"
|
||||
#include "iaxclient_lib.h"
|
||||
#include "gsm.h"
|
||||
|
||||
struct state {
|
||||
gsm gsmstate;
|
||||
plc_state_t plc;
|
||||
};
|
||||
|
||||
|
||||
static void destroy ( struct iaxc_audio_codec *c) {
|
||||
|
||||
struct state * encstate = (struct state *) c->encstate;
|
||||
struct state * decstate = (struct state *) c->decstate;
|
||||
|
||||
gsm_destroy(encstate->gsmstate);
|
||||
gsm_destroy(decstate->gsmstate);
|
||||
free(c->encstate);
|
||||
free(c->decstate);
|
||||
free(c);
|
||||
}
|
||||
|
||||
|
||||
static int decode ( struct iaxc_audio_codec *c,
|
||||
int *inlen, unsigned char *in, int *outlen, short *out ) {
|
||||
struct state * decstate = (struct state *) c->decstate;
|
||||
|
||||
/* use generic interpolation */
|
||||
if(*inlen == 0) {
|
||||
int interp_len = 160;
|
||||
if(*outlen < interp_len) interp_len = *outlen;
|
||||
plc_fillin(&decstate->plc,out,interp_len);
|
||||
*outlen -= interp_len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* need to decode minimum of 33 bytes to 160 byte output */
|
||||
while( (*inlen >= 33) && (*outlen >= 160) ) {
|
||||
if(gsm_decode(decstate->gsmstate, in, out))
|
||||
{
|
||||
fprintf(stderr, "codec_gsm: gsm_decode returned error\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* push decoded data to interpolation buffer */
|
||||
plc_rx(&decstate->plc,out,160);
|
||||
|
||||
/* we used 33 bytes of input, and 160 bytes of output */
|
||||
*inlen -= 33;
|
||||
in += 33;
|
||||
*outlen -= 160;
|
||||
out += 160;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int encode ( struct iaxc_audio_codec *c,
|
||||
int *inlen, short *in, int *outlen, unsigned char *out ) {
|
||||
|
||||
struct state * encstate = (struct state *) c->encstate;
|
||||
|
||||
|
||||
/* need to encode minimum of 160 bytes to 33 byte output */
|
||||
while( (*inlen >= 160) && (*outlen >= 33) ) {
|
||||
gsm_encode(encstate->gsmstate, in, out);
|
||||
|
||||
/* we used 160 bytes of input, and 33 bytes of output */
|
||||
*inlen -= 160;
|
||||
in += 160;
|
||||
*outlen -= 33;
|
||||
out += 33;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct iaxc_audio_codec *codec_audio_gsm_new() {
|
||||
|
||||
struct state * encstate;
|
||||
struct state * decstate;
|
||||
struct iaxc_audio_codec *c = (struct iaxc_audio_codec *)calloc(sizeof(struct iaxc_audio_codec),1);
|
||||
|
||||
|
||||
if(!c) return c;
|
||||
|
||||
strcpy(c->name,"gsm 06.10");
|
||||
c->format = IAXC_FORMAT_GSM;
|
||||
c->encode = encode;
|
||||
c->decode = decode;
|
||||
c->destroy = destroy;
|
||||
|
||||
c->minimum_frame_size = 160;
|
||||
|
||||
c->encstate = calloc(sizeof(struct state),1);
|
||||
c->decstate = calloc(sizeof(struct state),1);
|
||||
|
||||
/* leaks a bit on no-memory */
|
||||
if(!(c->encstate && c->decstate))
|
||||
return NULL;
|
||||
|
||||
encstate = (struct state *) c->encstate;
|
||||
decstate = (struct state *) c->decstate;
|
||||
|
||||
encstate->gsmstate = gsm_create();
|
||||
decstate->gsmstate = gsm_create();
|
||||
|
||||
if(!(encstate->gsmstate && decstate->gsmstate))
|
||||
return NULL;
|
||||
|
||||
return c;
|
||||
}
|
||||
|
15
utils/iaxclient/lib/codec_gsm.h
Normal file
15
utils/iaxclient/lib/codec_gsm.h
Normal file
|
@ -0,0 +1,15 @@
|
|||
/*
|
||||
* iaxclient: a cross-platform IAX softphone library
|
||||
*
|
||||
* Copyrights:
|
||||
* Copyright (C) 2003-2006, Horizon Wimba, Inc.
|
||||
* Copyright (C) 2007, Wimba, Inc.
|
||||
*
|
||||
* Contributors:
|
||||
* Steve Kann <stevek@stevek.com>
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU Lesser (Library) General Public License.
|
||||
*/
|
||||
|
||||
struct iaxc_audio_codec *codec_audio_gsm_new();
|
115
utils/iaxclient/lib/codec_ilbc.c
Normal file
115
utils/iaxclient/lib/codec_ilbc.c
Normal file
|
@ -0,0 +1,115 @@
|
|||
/*
|
||||
* iaxclient: a cross-platform IAX softphone library
|
||||
*
|
||||
* Copyrights:
|
||||
* Copyright (C) 2003-2006, Horizon Wimba, Inc.
|
||||
* Copyright (C) 2007, Wimba, Inc.
|
||||
*
|
||||
* Contributors:
|
||||
* Steve Kann <stevek@stevek.com>
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU Lesser (Library) General Public License.
|
||||
*/
|
||||
|
||||
#include "codec_ilbc.h"
|
||||
#include "iaxclient_lib.h"
|
||||
#include "iLBC/iLBC_encode.h"
|
||||
#include "iLBC/iLBC_decode.h"
|
||||
|
||||
|
||||
static void destroy ( struct iaxc_audio_codec *c) {
|
||||
free(c->encstate);
|
||||
free(c->decstate);
|
||||
free(c);
|
||||
}
|
||||
|
||||
|
||||
static int decode ( struct iaxc_audio_codec *c,
|
||||
int *inlen, char *in, int *outlen, short *out ) {
|
||||
|
||||
float fbuf[240];
|
||||
int i;
|
||||
|
||||
if(*inlen == 0) {
|
||||
//fprintf(stderr, "ILBC Interpolate\n");
|
||||
iLBC_decode(fbuf, NULL, c->decstate, 0);
|
||||
for(i=0;i<240;i++)
|
||||
out[i] = fbuf[i];
|
||||
*outlen -= 240;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* need to decode minimum of 33 bytes to 160 byte output */
|
||||
if( (*inlen < 50) || (*outlen < 240) ) {
|
||||
fprintf(stderr, "codec_ilbc: inlen = %d outlen= %d\n",*inlen,*outlen);
|
||||
return -1;
|
||||
}
|
||||
|
||||
while( (*inlen >= 50) && (*outlen >= 240) ) {
|
||||
iLBC_decode(fbuf, in, c->decstate, 1);
|
||||
for(i=0;i<240;i++)
|
||||
out[i] = fbuf[i];
|
||||
|
||||
out += 240;
|
||||
*outlen -= 240;
|
||||
in += 50;
|
||||
*inlen -= 50;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int encode ( struct iaxc_audio_codec *c,
|
||||
int *inlen, short *in, int *outlen, char *out ) {
|
||||
|
||||
float fbuf[240];
|
||||
int i;
|
||||
|
||||
while( (*inlen >= 240) && (*outlen >= 50) ) {
|
||||
|
||||
for(i=0;i<240;i++)
|
||||
fbuf[i] = in[i];
|
||||
|
||||
iLBC_encode(out,fbuf, c->encstate);
|
||||
|
||||
out += 50;
|
||||
*outlen -= 50;
|
||||
in += 240;
|
||||
*inlen -= 240;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct iaxc_audio_codec *codec_audio_ilbc_new() {
|
||||
struct iaxc_audio_codec *c = calloc(sizeof(struct iaxc_audio_codec),1);
|
||||
|
||||
|
||||
if(!c) return c;
|
||||
|
||||
strcpy(c->name,"iLBC");
|
||||
c->format = IAXC_FORMAT_ILBC;
|
||||
c->encode = encode;
|
||||
c->decode = decode;
|
||||
c->destroy = destroy;
|
||||
|
||||
c->minimum_frame_size = 240;
|
||||
|
||||
c->encstate = calloc(sizeof(iLBC_Enc_Inst_t),1);
|
||||
c->decstate = calloc(sizeof(iLBC_Dec_Inst_t),1);
|
||||
|
||||
/* leaks a bit on no-memory */
|
||||
if(!(c->encstate && c->decstate))
|
||||
return NULL;
|
||||
|
||||
/* the 30 parameters are used for the latest iLBC sources, in
|
||||
* http://www.ietf.org/internet-drafts/draft-ietf-avt-ilbc-codec-05.txt
|
||||
* as used in asterisk-CVS as of 14 Oct 2004 */
|
||||
initEncode(c->encstate, 30);
|
||||
initDecode(c->decstate, 30, 1); /* use enhancer */
|
||||
|
||||
return c;
|
||||
}
|
||||
|
15
utils/iaxclient/lib/codec_ilbc.h
Normal file
15
utils/iaxclient/lib/codec_ilbc.h
Normal file
|
@ -0,0 +1,15 @@
|
|||
/*
|
||||
* iaxclient: a cross-platform IAX softphone library
|
||||
*
|
||||
* Copyrights:
|
||||
* Copyright (C) 2003-2006, Horizon Wimba, Inc.
|
||||
* Copyright (C) 2007, Wimba, Inc.
|
||||
*
|
||||
* Contributors:
|
||||
* Steve Kann <stevek@stevek.com>
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU Lesser (Library) General Public License.
|
||||
*/
|
||||
|
||||
struct iaxc_audio_codec *codec_audio_ilbc_new();
|
190
utils/iaxclient/lib/codec_speex.c
Normal file
190
utils/iaxclient/lib/codec_speex.c
Normal file
|
@ -0,0 +1,190 @@
|
|||
/*
|
||||
* iaxclient: a cross-platform IAX softphone library
|
||||
*
|
||||
* Copyrights:
|
||||
* Copyright (C) 2003-2004, Horizon Wimba, Inc.
|
||||
* Copyright (C) 2007, Wimba, Inc.
|
||||
*
|
||||
* Contributors:
|
||||
* Steve Kann <stevek@stevek.com>
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU Lesser (Library) General Public License.
|
||||
*/
|
||||
|
||||
#include "codec_speex.h"
|
||||
#include "iaxclient_lib.h"
|
||||
#include "speex/speex.h"
|
||||
|
||||
struct State
|
||||
{
|
||||
void *state;
|
||||
int frame_size;
|
||||
SpeexBits bits;
|
||||
};
|
||||
|
||||
|
||||
static void destroy ( struct iaxc_audio_codec *c)
|
||||
{
|
||||
struct State * encstate = (struct State *) c->encstate;
|
||||
struct State * decstate = (struct State *) c->decstate;
|
||||
|
||||
speex_bits_destroy(&encstate->bits);
|
||||
speex_bits_destroy(&decstate->bits);
|
||||
speex_encoder_destroy(encstate->state);
|
||||
speex_decoder_destroy(decstate->state);
|
||||
|
||||
free(c->encstate);
|
||||
free(c->decstate);
|
||||
|
||||
free(c);
|
||||
}
|
||||
|
||||
|
||||
static int decode( struct iaxc_audio_codec *c,
|
||||
int *inlen, unsigned char *in, int *outlen, short *out )
|
||||
{
|
||||
struct State * decstate = (struct State *) c->decstate;
|
||||
|
||||
if ( *inlen == 0 )
|
||||
{
|
||||
speex_decode_int(decstate->state, NULL, out);
|
||||
*outlen -= decstate->frame_size;
|
||||
return 0;
|
||||
}
|
||||
|
||||
speex_bits_read_from(&decstate->bits, (char *) in, *inlen);
|
||||
*inlen = 0;
|
||||
|
||||
while ( speex_bits_remaining(&decstate->bits) &&
|
||||
*outlen >= decstate->frame_size )
|
||||
{
|
||||
int ret = speex_decode_int(decstate->state, &decstate->bits, out);
|
||||
|
||||
// from speex/speex.h, speex_decode returns:
|
||||
// @return return status (0 for no error, -1 for end of stream, -2 other)
|
||||
if (ret == 0)
|
||||
{
|
||||
/* one frame of output */
|
||||
*outlen -= decstate->frame_size;
|
||||
out += decstate->frame_size;
|
||||
} else if (ret == -1)
|
||||
{
|
||||
/* at end of stream, or just a terminator */
|
||||
int bits_left = speex_bits_remaining(&decstate->bits) % 8;
|
||||
if(bits_left >= 5)
|
||||
speex_bits_advance(&decstate->bits, bits_left);
|
||||
else
|
||||
break;
|
||||
} else
|
||||
{
|
||||
/* maybe there's not a whole frame somehow? */
|
||||
fprintf(stderr, "decode_int returned non-zero => %d\n",ret);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int encode( struct iaxc_audio_codec *c,
|
||||
int *inlen, short *in, int *outlen, unsigned char *out )
|
||||
{
|
||||
int bytes;
|
||||
struct State * encstate = (struct State *) c->encstate;
|
||||
|
||||
/* need to encode minimum of encstate->frame_size samples */
|
||||
|
||||
/* only add terminator at end of bits */
|
||||
speex_bits_reset(&encstate->bits);
|
||||
|
||||
/* need to encode minimum of encstate->frame_size samples */
|
||||
while(*inlen >= encstate->frame_size)
|
||||
{
|
||||
//fprintf(stderr, "encode: inlen=%d outlen=%d\n", *inlen, *outlen);
|
||||
speex_encode_int(encstate->state, in, &encstate->bits);
|
||||
*inlen -= encstate->frame_size;
|
||||
in += encstate->frame_size;
|
||||
}
|
||||
|
||||
/* add terminator */
|
||||
speex_bits_pack(&encstate->bits, 15, 5);
|
||||
|
||||
bytes = speex_bits_write(&encstate->bits, (char *) out, *outlen);
|
||||
|
||||
/* can an error happen here? no bytes? */
|
||||
*outlen -= bytes;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct iaxc_audio_codec *codec_audio_speex_new(struct iaxc_speex_settings *set)
|
||||
{
|
||||
struct State * encstate;
|
||||
struct State * decstate;
|
||||
struct iaxc_audio_codec *c = (struct iaxc_audio_codec *)calloc(sizeof(struct iaxc_audio_codec),1);
|
||||
const SpeexMode *sm;
|
||||
|
||||
if(!c)
|
||||
return c;
|
||||
|
||||
strcpy(c->name,"speex");
|
||||
c->format = IAXC_FORMAT_SPEEX;
|
||||
c->encode = encode;
|
||||
c->decode = decode;
|
||||
c->destroy = destroy;
|
||||
|
||||
c->encstate = calloc(sizeof(struct State),1);
|
||||
c->decstate = calloc(sizeof(struct State),1);
|
||||
|
||||
/* leaks a bit on no-memory */
|
||||
if(!(c->encstate && c->decstate))
|
||||
return NULL;
|
||||
|
||||
encstate = (struct State *) c->encstate;
|
||||
decstate = (struct State *) c->decstate;
|
||||
|
||||
sm = speex_lib_get_mode(SPEEX_MODEID_NB);
|
||||
|
||||
encstate->state = speex_encoder_init(sm);
|
||||
decstate->state = speex_decoder_init(sm);
|
||||
speex_bits_init(&encstate->bits);
|
||||
speex_bits_init(&decstate->bits);
|
||||
speex_bits_reset(&encstate->bits);
|
||||
speex_bits_reset(&decstate->bits);
|
||||
|
||||
speex_decoder_ctl(decstate->state, SPEEX_SET_ENH, &set->decode_enhance);
|
||||
|
||||
speex_encoder_ctl(encstate->state, SPEEX_SET_COMPLEXITY, &set->complexity);
|
||||
|
||||
if(set->quality >= 0) {
|
||||
if(set->vbr) {
|
||||
speex_encoder_ctl(encstate->state, SPEEX_SET_VBR_QUALITY, &set->quality);
|
||||
} else {
|
||||
int quality = (int)set->quality;
|
||||
speex_encoder_ctl(encstate->state, SPEEX_SET_QUALITY, &quality);
|
||||
}
|
||||
}
|
||||
if(set->bitrate >= 0)
|
||||
speex_encoder_ctl(encstate->state, SPEEX_SET_BITRATE, &set->bitrate);
|
||||
if(set->vbr)
|
||||
speex_encoder_ctl(encstate->state, SPEEX_SET_VBR, &set->vbr);
|
||||
if(set->abr)
|
||||
speex_encoder_ctl(encstate->state, SPEEX_SET_ABR, &set->abr);
|
||||
|
||||
/* set up frame sizes (normally, this is 20ms worth) */
|
||||
speex_encoder_ctl(encstate->state,SPEEX_GET_FRAME_SIZE,&encstate->frame_size);
|
||||
speex_decoder_ctl(decstate->state,SPEEX_GET_FRAME_SIZE,&decstate->frame_size);
|
||||
|
||||
c->minimum_frame_size = 160;
|
||||
|
||||
if(encstate->frame_size > c->minimum_frame_size)
|
||||
c->minimum_frame_size = encstate->frame_size;
|
||||
if(decstate->frame_size > c->minimum_frame_size)
|
||||
c->minimum_frame_size = decstate->frame_size;
|
||||
|
||||
if(!(encstate->state && decstate->state))
|
||||
return NULL;
|
||||
|
||||
return c;
|
||||
}
|
||||
|
26
utils/iaxclient/lib/codec_speex.h
Normal file
26
utils/iaxclient/lib/codec_speex.h
Normal file
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* iaxclient: a cross-platform IAX softphone library
|
||||
*
|
||||
* Copyrights:
|
||||
* Copyright (C) 2003-2006, Horizon Wimba, Inc.
|
||||
* Copyright (C) 2007, Wimba, Inc.
|
||||
*
|
||||
* Contributors:
|
||||
* Steve Kann <stevek@stevek.com>
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU Lesser (Library) General Public License.
|
||||
*/
|
||||
|
||||
#include "speex/speex.h"
|
||||
|
||||
struct iaxc_speex_settings {
|
||||
int decode_enhance;
|
||||
float quality;
|
||||
int bitrate;
|
||||
int vbr;
|
||||
int abr; /* abr bitrate */
|
||||
int complexity;
|
||||
};
|
||||
|
||||
struct iaxc_audio_codec *codec_audio_speex_new(struct iaxc_speex_settings *settings);
|
502
utils/iaxclient/lib/codec_theora.c
Normal file
502
utils/iaxclient/lib/codec_theora.c
Normal file
|
@ -0,0 +1,502 @@
|
|||
/*
|
||||
* iaxclient: a cross-platform IAX softphone library
|
||||
*
|
||||
* Copyrights:
|
||||
* Copyright (C) 2003-2006, Horizon Wimba, Inc.
|
||||
* Copyright (C) 2007, Wimba, Inc.
|
||||
*
|
||||
* Contributors:
|
||||
* Steve Kann <stevek@stevek.com>
|
||||
* Mihai Balea <mihai at hates dot ms>
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU Lesser (Library) General Public License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Some comments about Theora streaming
|
||||
* Theora video codec has two problems when it comes to streaming
|
||||
* and broadcasting video:
|
||||
*
|
||||
* - Large headers that need to be passed from the encoder to the decoder
|
||||
* to initialize it. The conventional wisdom says we should transfer the
|
||||
* headers out of band, but that complicates things with IAX, which does
|
||||
* not have a separate signalling channel. Also, it makes things really
|
||||
* difficult in a video conference scenario, where video gets switched
|
||||
* between participants regularly. To solve this issue, we initialize
|
||||
* the encoder and the decoder at the same time, using the headers from
|
||||
* the local encoder to initialize the decoder. This works if the
|
||||
* endpoints use the exact same version of Theora and the exact same
|
||||
* parameters for initialization.
|
||||
*
|
||||
* - No support for splitting the frame into multiple slices. Frames can
|
||||
* be relatively large. For a 320x240 video stream, you can see key
|
||||
* frames larger than 9KB, which is the maximum UDP packet size on Mac
|
||||
* OS X. To work around this limitation, we use the slice API to fragment
|
||||
* encoded frames to a reasonable size that UDP can safely transport
|
||||
*
|
||||
* Other miscellaneous comments:
|
||||
*
|
||||
* - For quality reasons, when we detect a video stream switch, we reject all
|
||||
* incoming frames until we receive a key frame.
|
||||
*
|
||||
* - Theora only accepts video that has dimensions multiple of 16. If we combine
|
||||
* his with a 4:3 aspect ratio requirement, we get a very limited number
|
||||
* of available resolutions. To work around this limitation, we pad the video
|
||||
* on encoding, up to the closest multiple of 16. On the decoding side, we
|
||||
* remove the padding. This way, video resolution can be any multiple of 2
|
||||
*
|
||||
* We should probably look more into this (how to deal with missing and
|
||||
* out of order slices)
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "iaxclient_lib.h"
|
||||
#include "video.h"
|
||||
#include "slice.h"
|
||||
#include "codec_theora.h"
|
||||
#include <theora/theora.h>
|
||||
|
||||
#define MAX_SLICE_SIZE 8000
|
||||
|
||||
struct theora_decoder
|
||||
{
|
||||
theora_state td;
|
||||
theora_info ti;
|
||||
theora_comment tc;
|
||||
struct deslicer_context *dsc;
|
||||
int got_key_frame;
|
||||
};
|
||||
|
||||
struct theora_encoder
|
||||
{
|
||||
theora_state td;
|
||||
theora_info ti;
|
||||
theora_comment tc;
|
||||
int needs_padding;
|
||||
struct slicer_context *sc;
|
||||
unsigned char *pad_buffer;
|
||||
};
|
||||
|
||||
static void destroy( struct iaxc_video_codec *c)
|
||||
{
|
||||
struct theora_encoder *e;
|
||||
struct theora_decoder *d;
|
||||
|
||||
if ( !c )
|
||||
return;
|
||||
|
||||
if ( c->encstate )
|
||||
{
|
||||
e = (struct theora_encoder *)c->encstate;
|
||||
if ( e->pad_buffer )
|
||||
free(e->pad_buffer);
|
||||
if ( e->sc )
|
||||
free_slicer_context(e->sc);
|
||||
theora_comment_clear(&e->tc);
|
||||
theora_info_clear(&e->ti);
|
||||
theora_clear(&e->td);
|
||||
free(e);
|
||||
}
|
||||
if ( c->decstate )
|
||||
{
|
||||
d = (struct theora_decoder *)c->decstate;
|
||||
if ( d->dsc )
|
||||
free_deslicer_context(d->dsc);
|
||||
theora_comment_clear(&d->tc);
|
||||
theora_info_clear(&d->ti);
|
||||
theora_clear(&d->td);
|
||||
free(c->decstate);
|
||||
}
|
||||
free(c);
|
||||
}
|
||||
|
||||
static int decode(struct iaxc_video_codec *c, int inlen, const char *in,
|
||||
int *outlen, char *out)
|
||||
{
|
||||
struct theora_decoder *d;
|
||||
ogg_packet op;
|
||||
yuv_buffer picture;
|
||||
unsigned int line;
|
||||
int my_out_len;
|
||||
int w, h, ph;
|
||||
int flen;
|
||||
char *frame;
|
||||
|
||||
// Sanity checks
|
||||
if ( !c || !c->decstate || !in || inlen <= 0 || !out || !outlen )
|
||||
return -1;
|
||||
|
||||
// Assemble slices
|
||||
d = (struct theora_decoder *)c->decstate;
|
||||
if ( !d->dsc )
|
||||
return -1;
|
||||
|
||||
frame = deslice(in, inlen, &flen, d->dsc);
|
||||
if ( frame == NULL )
|
||||
return 1;
|
||||
|
||||
/* decode into an OP structure */
|
||||
memset(&op, 0, sizeof(op));
|
||||
op.bytes = flen;
|
||||
op.packet = (unsigned char *)frame;
|
||||
|
||||
/* reject all incoming frames until we get a key frame */
|
||||
if ( !d->got_key_frame )
|
||||
{
|
||||
if ( theora_packet_iskeyframe(&op) )
|
||||
d->got_key_frame = 1;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ( theora_decode_packetin(&d->td, &op) == OC_BADPACKET )
|
||||
{
|
||||
fprintf(stderr,
|
||||
"codec_theora: warning: theora_decode_packetin says bad packet\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
w = d->ti.frame_width;
|
||||
h = d->ti.frame_height;
|
||||
ph = d->ti.height;
|
||||
|
||||
my_out_len = d->ti.frame_width * d->ti.frame_height * 3 / 2;
|
||||
|
||||
/* make sure we have enough room for the goodies */
|
||||
if ( *outlen < my_out_len )
|
||||
{
|
||||
fprintf(stderr, "codec_theora: not enough room for decoding\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* finally, here's where we get our goodies */
|
||||
if ( theora_decode_YUVout(&d->td, &picture) )
|
||||
{
|
||||
fprintf(stderr, "codec_theora: error getting our goodies\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
//clear output
|
||||
memset(out, 127, my_out_len);
|
||||
|
||||
for( line = 0 ; line < d->ti.frame_height / 2 ; line++ )
|
||||
{
|
||||
// Y-even
|
||||
memcpy(out + picture.y_width * 2 * line,
|
||||
picture.y + 2 * line * picture.y_stride,
|
||||
picture.y_width);
|
||||
// Y-odd
|
||||
memcpy(out + picture.y_width * (2 * line + 1),
|
||||
picture.y + (2 * line + 1) * picture.y_stride,
|
||||
picture.y_width);
|
||||
// U + V
|
||||
memcpy(out + (d->ti.frame_width * d->ti.frame_height) + line * d->ti.frame_width / 2,
|
||||
picture.u + line * picture.uv_stride,
|
||||
picture.uv_width);
|
||||
memcpy(out + (d->ti.frame_width * d->ti.frame_height * 5 / 4) + line * d->ti.frame_width / 2,
|
||||
picture.v + line * picture.uv_stride,
|
||||
picture.uv_width);
|
||||
}
|
||||
|
||||
*outlen = my_out_len;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Pads a w by h frame to bring it up to pw by ph size using value
|
||||
static void pad_channel(const char *src, int w, int h, unsigned char *dst,
|
||||
int pw, int ph, unsigned char value)
|
||||
{
|
||||
int i;
|
||||
|
||||
if ( w == pw )
|
||||
{
|
||||
// We don't need to pad each line, just copy the data
|
||||
memcpy(dst, src, w * h);
|
||||
} else
|
||||
{
|
||||
// We DO need to pad each line
|
||||
for ( i=0 ; i<h ; i++ )
|
||||
{
|
||||
memcpy(&dst[i*pw], &src[i*w], w);
|
||||
memset(&dst[i*pw+w], value, pw-w);
|
||||
}
|
||||
}
|
||||
// Pad the bottom of the frame if necessary
|
||||
if ( h < ph )
|
||||
memset(dst + pw * h, value, (ph - h) * pw);
|
||||
}
|
||||
|
||||
static int encode(struct iaxc_video_codec * c, int inlen, const char * in,
|
||||
struct slice_set_t * slice_set)
|
||||
{
|
||||
struct theora_encoder *e;
|
||||
ogg_packet op;
|
||||
yuv_buffer picture;
|
||||
|
||||
// Sanity checks
|
||||
if ( !c || !c->encstate || !in || !slice_set )
|
||||
return -1;
|
||||
|
||||
e = (struct theora_encoder *)c->encstate;
|
||||
|
||||
// Prepare the YUV buffer
|
||||
if ( e->needs_padding )
|
||||
{
|
||||
// We copy a padded image into the pad buffer and set up the pointers
|
||||
// Use pad_channel for each of the YUV channels
|
||||
// Use a pad value of 0 for luma and 128 for chroma
|
||||
pad_channel(in,
|
||||
e->ti.frame_width,
|
||||
e->ti.frame_height,
|
||||
e->pad_buffer,
|
||||
e->ti.width,
|
||||
e->ti.height,
|
||||
0);
|
||||
|
||||
pad_channel(in + e->ti.frame_width * e->ti.frame_height,
|
||||
e->ti.frame_width / 2,
|
||||
e->ti.frame_height / 2,
|
||||
e->pad_buffer + e->ti.width * e->ti.height,
|
||||
e->ti.width / 2,
|
||||
e->ti.height / 2,
|
||||
128);
|
||||
|
||||
pad_channel(in + e->ti.frame_width * e->ti.frame_height * 5 / 4,
|
||||
e->ti.frame_width / 2,
|
||||
e->ti.frame_height / 2,
|
||||
e->pad_buffer + e->ti.width * e->ti.height * 5 / 4,
|
||||
e->ti.width / 2,
|
||||
e->ti.height / 2,
|
||||
128);
|
||||
|
||||
picture.y = e->pad_buffer;
|
||||
} else
|
||||
{
|
||||
// use the original buffer
|
||||
picture.y = (unsigned char *)in;
|
||||
}
|
||||
picture.u = picture.y + e->ti.width * e->ti.height;
|
||||
picture.v = picture.u + e->ti.width * e->ti.height / 4;
|
||||
picture.y_width = e->ti.width;
|
||||
picture.y_height = e->ti.height;
|
||||
picture.y_stride = e->ti.width;
|
||||
picture.uv_width = e->ti.width / 2;
|
||||
picture.uv_height = e->ti.height / 2;
|
||||
picture.uv_stride = e->ti.width / 2;
|
||||
|
||||
// Send data in for encoding
|
||||
if ( theora_encode_YUVin(&e->td, &picture) )
|
||||
{
|
||||
fprintf(stderr, "codec_theora: failed theora_encode_YUVin\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Get data from the encoder
|
||||
if ( theora_encode_packetout(&e->td, 0, &op) != 1 )
|
||||
{
|
||||
fprintf(stderr, "codec_theora: failed theora_encode_packetout\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Check to see if we have a key frame
|
||||
slice_set->key_frame = theora_packet_iskeyframe(&op) == 1;
|
||||
|
||||
// Slice the frame
|
||||
slice((char *)op.packet, op.bytes, slice_set, e->sc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct iaxc_video_codec *codec_video_theora_new(int format, int w, int h,
|
||||
int framerate, int bitrate, int fragsize)
|
||||
{
|
||||
struct iaxc_video_codec *c;
|
||||
struct theora_encoder *e;
|
||||
struct theora_decoder *d;
|
||||
unsigned short source_id;
|
||||
ogg_packet headerp, commentp, tablep;
|
||||
|
||||
/* Basic sanity checks */
|
||||
if ( w <= 0 || h <= 0 || framerate <= 0 || bitrate <= 0 || fragsize <= 0 )
|
||||
{
|
||||
fprintf(stderr, "codec_theora: bogus codec params: %d %d %d %d %d\n",
|
||||
w, h, framerate, bitrate, fragsize);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ( w % 2 || h % 2 )
|
||||
{
|
||||
fprintf(stderr, "codec_theora: video dimensions must be multiples of 2\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ( fragsize > MAX_SLICE_SIZE )
|
||||
fragsize = MAX_SLICE_SIZE;
|
||||
|
||||
c = (struct iaxc_video_codec *)calloc(sizeof(struct iaxc_video_codec), 1);
|
||||
|
||||
if ( !c )
|
||||
goto bail;
|
||||
|
||||
c->decstate = calloc(sizeof(struct theora_decoder), 1);
|
||||
|
||||
if ( !c->decstate )
|
||||
goto bail;
|
||||
|
||||
c->encstate = calloc(sizeof(struct theora_encoder), 1);
|
||||
|
||||
if ( !c->encstate )
|
||||
goto bail;
|
||||
|
||||
c->format = format;
|
||||
c->width = w;
|
||||
c->height = h;
|
||||
c->framerate = framerate;
|
||||
c->bitrate = bitrate;
|
||||
c->fragsize = fragsize;
|
||||
|
||||
c->encode = encode;
|
||||
c->decode = decode;
|
||||
c->destroy = destroy;
|
||||
|
||||
e = (struct theora_encoder *)c->encstate;
|
||||
d = (struct theora_decoder *)c->decstate;
|
||||
|
||||
// Initialize slicer
|
||||
// Generate random source id
|
||||
srand((unsigned int)time(0));
|
||||
source_id = rand() & 0xffff;
|
||||
e->sc = create_slicer_context(source_id, fragsize);
|
||||
if ( !e->sc )
|
||||
goto bail;
|
||||
|
||||
|
||||
/* set up some parameters in the contexts */
|
||||
|
||||
theora_info_init(&e->ti);
|
||||
|
||||
/* set up common parameters */
|
||||
e->ti.frame_width = w;
|
||||
e->ti.frame_height = h;
|
||||
e->ti.width = ((w - 1) / 16 + 1) * 16;
|
||||
e->ti.height = ((h - 1) / 16 + 1) * 16;
|
||||
e->ti.offset_x = 0;
|
||||
e->ti.offset_y = 0;
|
||||
|
||||
// We set up a padded frame with dimensions that are multiple of 16
|
||||
// We allocate a buffer to hold this frame
|
||||
e->needs_padding = e->ti.width != e->ti.frame_width ||
|
||||
e->ti.height != e->ti.frame_height;
|
||||
|
||||
if ( e->needs_padding )
|
||||
{
|
||||
e->pad_buffer = (unsigned char *)
|
||||
malloc(e->ti.width * e->ti.height * 3 / 2);
|
||||
|
||||
if ( !e->pad_buffer )
|
||||
goto bail;
|
||||
}
|
||||
else
|
||||
{
|
||||
e->pad_buffer = 0;
|
||||
}
|
||||
|
||||
e->ti.fps_numerator = framerate;
|
||||
e->ti.fps_denominator = 1;
|
||||
|
||||
e->ti.aspect_numerator = 1;
|
||||
e->ti.aspect_denominator = 1;
|
||||
|
||||
e->ti.colorspace = OC_CS_UNSPECIFIED;
|
||||
e->ti.pixelformat = OC_PF_420;
|
||||
|
||||
e->ti.target_bitrate = bitrate;
|
||||
|
||||
e->ti.quality = 0;
|
||||
|
||||
e->ti.dropframes_p = 0;
|
||||
e->ti.quick_p = 1;
|
||||
e->ti.keyframe_auto_p = 0;
|
||||
e->ti.keyframe_frequency = framerate;
|
||||
e->ti.keyframe_frequency_force = framerate;
|
||||
e->ti.keyframe_data_target_bitrate = bitrate * 3;
|
||||
e->ti.keyframe_auto_threshold = 80;
|
||||
e->ti.keyframe_mindistance = 8;
|
||||
e->ti.noise_sensitivity = 0;
|
||||
|
||||
if ( theora_encode_init(&e->td, &e->ti) )
|
||||
goto bail;
|
||||
|
||||
// Obtain the encoder headers and set up the decoder headers from
|
||||
// data in the encoder headers
|
||||
memset(&headerp, 0, sizeof(headerp));
|
||||
memset(&commentp, 0, sizeof(commentp));
|
||||
memset(&tablep, 0, sizeof(tablep));
|
||||
|
||||
// Set up the decoder using the encoder headers
|
||||
theora_info_init(&d->ti);
|
||||
theora_comment_init(&d->tc);
|
||||
theora_comment_init(&e->tc);
|
||||
|
||||
if ( theora_encode_header(&e->td, &headerp) )
|
||||
goto bail;
|
||||
|
||||
headerp.b_o_s = 1;
|
||||
|
||||
if ( theora_decode_header(&d->ti, &d->tc, &headerp) )
|
||||
goto bail;
|
||||
|
||||
if ( theora_encode_comment(&e->tc, &commentp) )
|
||||
goto bail;
|
||||
|
||||
if ( theora_decode_header(&d->ti, &d->tc, &commentp) )
|
||||
goto bail;
|
||||
|
||||
theora_comment_clear(&e->tc);
|
||||
|
||||
if ( theora_encode_tables(&e->td, &tablep) )
|
||||
goto bail;
|
||||
|
||||
if ( theora_decode_header(&d->ti, &d->tc, &tablep) )
|
||||
goto bail;
|
||||
|
||||
if ( theora_decode_init(&d->td, &d->ti) )
|
||||
goto bail;
|
||||
|
||||
d->got_key_frame = 0;
|
||||
|
||||
// Initialize deslicer context
|
||||
d->dsc = create_deslicer_context(c->fragsize);
|
||||
if ( !d->dsc )
|
||||
goto bail;
|
||||
|
||||
strcpy(c->name, "Theora");
|
||||
return c;
|
||||
|
||||
bail:
|
||||
fprintf(stderr, "codec_theora: failed to initialize encoder or decoder\n");
|
||||
|
||||
if ( c )
|
||||
{
|
||||
if ( c->encstate )
|
||||
{
|
||||
e = (struct theora_encoder *)c->encstate;
|
||||
if ( e->sc )
|
||||
free_slicer_context(e->sc);
|
||||
free(c->encstate);
|
||||
}
|
||||
if ( c->decstate )
|
||||
{
|
||||
d = (struct theora_decoder *)c->decstate;
|
||||
if ( d->dsc )
|
||||
free_deslicer_context(d->dsc);
|
||||
free(c->decstate);
|
||||
}
|
||||
free(c);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
17
utils/iaxclient/lib/codec_theora.h
Normal file
17
utils/iaxclient/lib/codec_theora.h
Normal file
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* iaxclient: a cross-platform IAX softphone library
|
||||
*
|
||||
* Copyrights:
|
||||
* Copyright (C) 2003-2006, Horizon Wimba, Inc.
|
||||
* Copyright (C) 2007, Wimba, Inc.
|
||||
*
|
||||
* Contributors:
|
||||
* Steve Kann <stevek@stevek.com>
|
||||
* Mihai Balea <mihai at hates dot ms>
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU Lesser (Library) General Public License.
|
||||
*/
|
||||
|
||||
struct iaxc_video_codec *codec_video_theora_new(int format, int w, int h,
|
||||
int framerate, int bitrate, int fragsize);
|
152
utils/iaxclient/lib/codec_ulaw.c
Normal file
152
utils/iaxclient/lib/codec_ulaw.c
Normal file
|
@ -0,0 +1,152 @@
|
|||
/*
|
||||
* iaxclient: a cross-platform IAX softphone library
|
||||
*
|
||||
* Copyrights:
|
||||
* Copyright (C) 2003-2006, Horizon Wimba, Inc.
|
||||
* Copyright (C) 2007, Wimba, Inc.
|
||||
*
|
||||
* Contributors:
|
||||
* Steve Kann <stevek@stevek.com>
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU Lesser (Library) General Public License.
|
||||
*/
|
||||
|
||||
#include "codec_ulaw.h"
|
||||
#include "iaxclient_lib.h"
|
||||
|
||||
struct state {
|
||||
plc_state_t plc;
|
||||
};
|
||||
|
||||
static short ulaw_2lin [256];
|
||||
static unsigned char lin_2ulaw [16384];
|
||||
static int initialized=0;
|
||||
|
||||
/* this looks similar to asterisk, but comes from public domain code by craig reese
|
||||
I've just followed asterisk's table sizes for lin_2u, and also too lazy to do binary arith to decide which
|
||||
iterations to skip -- this way we get the same result.. */
|
||||
static void initialize() {
|
||||
int i;
|
||||
|
||||
/* ulaw_2lin */
|
||||
for(i=0;i<256;i++) {
|
||||
int b = ~i;
|
||||
int exp_lut[8] = {0,132,396,924,1980,4092,8316,16764};
|
||||
int sign, exponent, mantissa, sample;
|
||||
|
||||
sign = (b & 0x80);
|
||||
exponent = (b >> 4) & 0x07;
|
||||
mantissa = b & 0x0F;
|
||||
sample = exp_lut[exponent] + (mantissa << (exponent + 3));
|
||||
if (sign != 0) sample = -sample;
|
||||
ulaw_2lin[i] = sample;
|
||||
}
|
||||
|
||||
/* lin_2ulaw */
|
||||
for(i=-32767;i<32768;i+=4) {
|
||||
int sample = i;
|
||||
int exp_lut[256] = {0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
|
||||
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
|
||||
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
|
||||
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
|
||||
6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
|
||||
6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
|
||||
6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
|
||||
6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
|
||||
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
|
||||
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
|
||||
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
|
||||
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
|
||||
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
|
||||
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
|
||||
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
|
||||
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7};
|
||||
int sign, exponent, mantissa;
|
||||
unsigned char ulawbyte;
|
||||
|
||||
/* Get the sample into sign-magnitude. */
|
||||
sign = (sample >> 8) & 0x80; /* set aside the sign */
|
||||
if (sign != 0) sample = -sample; /* get magnitude */
|
||||
if (sample > 32635) sample = 32635; /* clip the magnitude */
|
||||
|
||||
/* Convert from 16 bit linear to ulaw. */
|
||||
sample = sample + 0x84;
|
||||
exponent = exp_lut[(sample >> 7) & 0xFF];
|
||||
mantissa = (sample >> (exponent + 3)) & 0x0F;
|
||||
ulawbyte = ~(sign | (exponent << 4) | mantissa);
|
||||
if (ulawbyte == 0) ulawbyte = 0x02; /* optional CCITT trap */
|
||||
|
||||
lin_2ulaw[((unsigned short)i) >> 2] = ulawbyte;
|
||||
}
|
||||
|
||||
initialized = 1;
|
||||
}
|
||||
|
||||
static void destroy ( struct iaxc_audio_codec *c) {
|
||||
if ( c->decstate )
|
||||
free(c->decstate);
|
||||
free(c);
|
||||
}
|
||||
|
||||
|
||||
static int decode ( struct iaxc_audio_codec *c,
|
||||
int *inlen, unsigned char *in, int *outlen, short *out ) {
|
||||
struct state *state = (struct state *)c->decstate;
|
||||
short *orig_out = out;
|
||||
short sample;
|
||||
|
||||
if(*inlen == 0) {
|
||||
int interp_len = 160;
|
||||
if(*outlen < interp_len) interp_len = *outlen;
|
||||
plc_fillin(&state->plc,out,interp_len);
|
||||
*outlen -= interp_len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
while ((*inlen > 0) && (*outlen > 0)) {
|
||||
sample = ulaw_2lin[(unsigned char)*(in++)];
|
||||
*(out++) = sample;
|
||||
(*inlen)--; (*outlen)--;
|
||||
}
|
||||
plc_rx(&state->plc, orig_out, (int)(out - orig_out));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int encode ( struct iaxc_audio_codec *c,
|
||||
int *inlen, short *in, int *outlen, unsigned char *out ) {
|
||||
|
||||
while ((*inlen > 0) && (*outlen > 0)) {
|
||||
*(out++) = lin_2ulaw[((unsigned short)*(in++)) >> 2];
|
||||
(*inlen)--; (*outlen)--;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
struct iaxc_audio_codec *codec_audio_ulaw_new() {
|
||||
|
||||
struct iaxc_audio_codec *c = (struct iaxc_audio_codec *)calloc(sizeof(struct iaxc_audio_codec),1);
|
||||
|
||||
if(!c) return c;
|
||||
|
||||
if(!initialized) initialize();
|
||||
|
||||
strcpy(c->name,"ulaw");
|
||||
c->format = IAXC_FORMAT_ULAW;
|
||||
c->encode = encode;
|
||||
c->decode = decode;
|
||||
c->destroy = destroy;
|
||||
|
||||
/* really, we can use less, but don't want to */
|
||||
c->minimum_frame_size = 160;
|
||||
|
||||
/* decoder state, used for interpolation */
|
||||
c->decstate = calloc(sizeof(struct state),1);
|
||||
plc_init(&((struct state *)c->decstate)->plc);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
15
utils/iaxclient/lib/codec_ulaw.h
Normal file
15
utils/iaxclient/lib/codec_ulaw.h
Normal file
|
@ -0,0 +1,15 @@
|
|||
/*
|
||||
* iaxclient: a cross-platform IAX softphone library
|
||||
*
|
||||
* Copyrights:
|
||||
* Copyright (C) 2003-2006, Horizon Wimba, Inc.
|
||||
* Copyright (C) 2007, Wimba, Inc.
|
||||
*
|
||||
* Contributors:
|
||||
* Steve Kann <stevek@stevek.com>
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU Lesser (Library) General Public License.
|
||||
*/
|
||||
|
||||
struct iaxc_audio_codec *codec_audio_ulaw_new();
|
16
utils/iaxclient/lib/gsm/copyright
Normal file
16
utils/iaxclient/lib/gsm/copyright
Normal file
|
@ -0,0 +1,16 @@
|
|||
Copyright 1992, 1993, 1994 by Jutta Degener and Carsten Bormann,
|
||||
Technische Universitaet Berlin
|
||||
|
||||
Any use of this software is permitted provided that this notice is not
|
||||
removed and that neither the authors nor the Technische Universitaet Berlin
|
||||
are deemed to have made any representations as to the suitability of this
|
||||
software for any purpose nor are held responsible for any defects of
|
||||
this software. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
|
||||
|
||||
As a matter of courtesy, the authors request to be informed about uses
|
||||
this software has found, about bugs in this software, and about any
|
||||
improvements that may be of general interest.
|
||||
|
||||
Berlin, 28.11.1994
|
||||
Jutta Degener
|
||||
Carsten Bormann
|
37
utils/iaxclient/lib/gsm/inc/config.h
Normal file
37
utils/iaxclient/lib/gsm/inc/config.h
Normal file
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
|
||||
* Universitaet Berlin. See the accompanying file "COPYRIGHT" for
|
||||
* details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*$Header$*/
|
||||
|
||||
#ifndef CONFIG_H
|
||||
#define CONFIG_H
|
||||
|
||||
/*efine SIGHANDLER_T int / * signal handlers are void */
|
||||
/*efine HAS_SYSV_SIGNAL 1 / * sigs not blocked/reset? */
|
||||
|
||||
#define HAS_STDLIB_H 1 /* /usr/include/stdlib.h */
|
||||
/*efine HAS_LIMITS_H 1 / * /usr/include/limits.h */
|
||||
#define HAS_FCNTL_H 1 /* /usr/include/fcntl.h */
|
||||
/*efine HAS_ERRNO_DECL 1 / * errno.h declares errno */
|
||||
|
||||
#define HAS_FSTAT 1 /* fstat syscall */
|
||||
#define HAS_FCHMOD 1 /* fchmod syscall */
|
||||
#define HAS_CHMOD 1 /* chmod syscall */
|
||||
#define HAS_FCHOWN 1 /* fchown syscall */
|
||||
#define HAS_CHOWN 1 /* chown syscall */
|
||||
/*efine HAS__FSETMODE 1 / * _fsetmode -- set file mode */
|
||||
|
||||
#define HAS_STRING_H 1 /* /usr/include/string.h */
|
||||
/*efine HAS_STRINGS_H 1 / * /usr/include/strings.h */
|
||||
|
||||
#define HAS_UNISTD_H 1 /* /usr/include/unistd.h */
|
||||
#define HAS_UTIME 1 /* POSIX utime(path, times) */
|
||||
/*efine HAS_UTIMES 1 / * use utimes() syscall instead */
|
||||
#define HAS_UTIME_H 1 /* UTIME header file */
|
||||
/*efine HAS_UTIMBUF 1 / * struct utimbuf */
|
||||
/*efine HAS_UTIMEUSEC 1 / * microseconds in utimbuf? */
|
||||
|
||||
#endif /* CONFIG_H */
|
71
utils/iaxclient/lib/gsm/inc/gsm.h
Normal file
71
utils/iaxclient/lib/gsm/inc/gsm.h
Normal file
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
|
||||
* Universitaet Berlin. See the accompanying file "COPYRIGHT" for
|
||||
* details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*$Header$*/
|
||||
|
||||
#ifndef GSM_H
|
||||
#define GSM_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
# define NeedFunctionPrototypes 1
|
||||
#endif
|
||||
|
||||
#if __STDC__
|
||||
# define NeedFunctionPrototypes 1
|
||||
#endif
|
||||
|
||||
#ifdef _NO_PROTO
|
||||
# undef NeedFunctionPrototypes
|
||||
#endif
|
||||
|
||||
#ifdef NeedFunctionPrototypes
|
||||
# include <stdio.h> /* for FILE * */
|
||||
#endif
|
||||
|
||||
#undef GSM_P
|
||||
#if NeedFunctionPrototypes
|
||||
# define GSM_P( protos ) protos
|
||||
#else
|
||||
# define GSM_P( protos ) ( /* protos */ )
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Interface
|
||||
*/
|
||||
|
||||
typedef struct gsm_state * gsm;
|
||||
typedef short gsm_signal; /* signed 16 bit */
|
||||
typedef unsigned char gsm_byte;
|
||||
typedef gsm_byte gsm_frame[33]; /* 33 * 8 bits */
|
||||
|
||||
#define GSM_MAGIC 0xD /* 13 kbit/s RPE-LTP */
|
||||
|
||||
#define GSM_PATCHLEVEL 10
|
||||
#define GSM_MINOR 0
|
||||
#define GSM_MAJOR 1
|
||||
|
||||
#define GSM_OPT_VERBOSE 1
|
||||
#define GSM_OPT_FAST 2
|
||||
#define GSM_OPT_LTP_CUT 3
|
||||
#define GSM_OPT_WAV49 4
|
||||
#define GSM_OPT_FRAME_INDEX 5
|
||||
#define GSM_OPT_FRAME_CHAIN 6
|
||||
|
||||
extern gsm gsm_create GSM_P((void));
|
||||
extern void gsm_destroy GSM_P((gsm));
|
||||
|
||||
extern int gsm_print GSM_P((FILE *, gsm, gsm_byte *));
|
||||
extern int gsm_option GSM_P((gsm, int, int *));
|
||||
|
||||
extern void gsm_encode GSM_P((gsm, gsm_signal *, gsm_byte *));
|
||||
extern int gsm_decode GSM_P((gsm, gsm_byte *, gsm_signal *));
|
||||
|
||||
extern int gsm_explode GSM_P((gsm, gsm_byte *, gsm_signal *));
|
||||
extern void gsm_implode GSM_P((gsm, gsm_signal *, gsm_byte *));
|
||||
|
||||
#undef GSM_P
|
||||
|
||||
#endif /* GSM_H */
|
308
utils/iaxclient/lib/gsm/inc/private.h
Normal file
308
utils/iaxclient/lib/gsm/inc/private.h
Normal file
|
@ -0,0 +1,308 @@
|
|||
/*
|
||||
* Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
|
||||
* Universitaet Berlin. See the accompanying file "COPYRIGHT" for
|
||||
* details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*$Header$*/
|
||||
|
||||
#ifndef PRIVATE_H
|
||||
#define PRIVATE_H
|
||||
|
||||
typedef short word; /* 16 bit signed int */
|
||||
typedef long longword; /* 32 bit signed int */
|
||||
|
||||
typedef unsigned short uword; /* unsigned word */
|
||||
typedef unsigned long ulongword; /* unsigned longword */
|
||||
|
||||
struct gsm_state {
|
||||
|
||||
word dp0[ 280 ];
|
||||
|
||||
word z1; /* preprocessing.c, Offset_com. */
|
||||
longword L_z2; /* Offset_com. */
|
||||
int mp; /* Preemphasis */
|
||||
|
||||
word u[8]; /* short_term_aly_filter.c */
|
||||
word LARpp[2][8]; /* */
|
||||
word j; /* */
|
||||
|
||||
word ltp_cut; /* long_term.c, LTP crosscorr. */
|
||||
word nrp; /* 40 */ /* long_term.c, synthesis */
|
||||
word v[9]; /* short_term.c, synthesis */
|
||||
word msr; /* decoder.c, Postprocessing */
|
||||
|
||||
char verbose; /* only used if !NDEBUG */
|
||||
char fast; /* only used if FAST */
|
||||
|
||||
char wav_fmt; /* only used if WAV49 defined */
|
||||
unsigned char frame_index; /* odd/even chaining */
|
||||
unsigned char frame_chain; /* half-byte to carry forward */
|
||||
};
|
||||
|
||||
|
||||
#define MIN_WORD (-32767 - 1)
|
||||
#define MAX_WORD 32767
|
||||
|
||||
#define MIN_LONGWORD (-2147483647 - 1)
|
||||
#define MAX_LONGWORD 2147483647
|
||||
|
||||
#ifdef SASR /* flag: >> is a signed arithmetic shift right */
|
||||
#undef SASR
|
||||
#define SASR(x, by) ((x) >> (by))
|
||||
#else
|
||||
#define SASR(x, by) ((x) >= 0 ? (x) >> (by) : (~(-((x) + 1) >> (by))))
|
||||
#endif /* SASR */
|
||||
|
||||
#include "proto.h"
|
||||
|
||||
/*
|
||||
* Prototypes from add.c
|
||||
*/
|
||||
extern word gsm_mult P((word a, word b));
|
||||
extern longword gsm_L_mult P((word a, word b));
|
||||
extern word gsm_mult_r P((word a, word b));
|
||||
|
||||
extern word gsm_div P((word num, word denum));
|
||||
|
||||
extern word gsm_add P(( word a, word b ));
|
||||
extern longword gsm_L_add P(( longword a, longword b ));
|
||||
|
||||
extern word gsm_sub P((word a, word b));
|
||||
extern longword gsm_L_sub P((longword a, longword b));
|
||||
|
||||
extern word gsm_abs P((word a));
|
||||
|
||||
extern word gsm_norm P(( longword a ));
|
||||
|
||||
extern longword gsm_L_asl P((longword a, int n));
|
||||
extern word gsm_asl P((word a, int n));
|
||||
|
||||
extern longword gsm_L_asr P((longword a, int n));
|
||||
extern word gsm_asr P((word a, int n));
|
||||
|
||||
/*
|
||||
* Inlined functions from add.h
|
||||
*/
|
||||
|
||||
/*
|
||||
* #define GSM_MULT_R(a, b) (* word a, word b, !(a == b == MIN_WORD) *) \
|
||||
* (0x0FFFF & SASR(((longword)(a) * (longword)(b) + 16384), 15))
|
||||
*/
|
||||
#define GSM_MULT_R(a, b) /* word a, word b, !(a == b == MIN_WORD) */ \
|
||||
(SASR( ((longword)(a) * (longword)(b) + 16384), 15 ))
|
||||
|
||||
# define GSM_MULT(a,b) /* word a, word b, !(a == b == MIN_WORD) */ \
|
||||
(SASR( ((longword)(a) * (longword)(b)), 15 ))
|
||||
|
||||
# define GSM_L_MULT(a, b) /* word a, word b */ \
|
||||
(((longword)(a) * (longword)(b)) << 1)
|
||||
|
||||
#if defined(__GNUC__) && defined(__i386__)
|
||||
|
||||
static __inline__ int GSM_L_ADD(int a, int b)
|
||||
{
|
||||
__asm__ __volatile__(
|
||||
|
||||
"addl %2,%0; jno 0f; movl $0x7fffffff,%0; adcl $0,%0; 0:"
|
||||
: "=r" (a)
|
||||
: "0" (a), "ir" (b)
|
||||
: "cc"
|
||||
);
|
||||
return(a);
|
||||
}
|
||||
|
||||
static __inline__ short GSM_ADD(short a, short b)
|
||||
{
|
||||
__asm__ __volatile__(
|
||||
"addw %2,%0; jno 0f; movw $0x7fff,%0; adcw $0,%0; 0:"
|
||||
: "=r" (a)
|
||||
: "0" (a), "ir" (b)
|
||||
: "cc"
|
||||
);
|
||||
return(a);
|
||||
}
|
||||
|
||||
static __inline__ short GSM_SUB(short a, short b)
|
||||
{
|
||||
__asm__ __volatile__(
|
||||
"subw %2,%0; jno 0f; movw $0x7fff,%0; adcw $0,%0; 0:"
|
||||
: "=r" (a)
|
||||
: "0" (a), "ir" (b)
|
||||
: "cc"
|
||||
);
|
||||
return(a);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
# define GSM_L_ADD(a, b) \
|
||||
( (a) < 0 ? ( (b) >= 0 ? (a) + (b) \
|
||||
: (utmp = (ulongword)-((a) + 1) + (ulongword)-((b) + 1)) \
|
||||
>= MAX_LONGWORD ? MIN_LONGWORD : -(longword)utmp-2 ) \
|
||||
: ((b) <= 0 ? (a) + (b) \
|
||||
: (utmp = (ulongword)(a) + (ulongword)(b)) >= MAX_LONGWORD \
|
||||
? MAX_LONGWORD : utmp))
|
||||
|
||||
/*
|
||||
* # define GSM_ADD(a, b) \
|
||||
* ((ltmp = (longword)(a) + (longword)(b)) >= MAX_WORD \
|
||||
* ? MAX_WORD : ltmp <= MIN_WORD ? MIN_WORD : ltmp)
|
||||
*/
|
||||
/* Nonportable, but faster: */
|
||||
|
||||
#define GSM_ADD(a, b) \
|
||||
(short) ((ulongword)((ltmp = (longword)(a) + (longword)(b)) - MIN_WORD) > \
|
||||
MAX_WORD - MIN_WORD ? (ltmp > 0 ? MAX_WORD : MIN_WORD) : ltmp)
|
||||
|
||||
# define GSM_SUB(a, b) \
|
||||
((ltmp = (longword)(a) - (longword)(b)) >= MAX_WORD \
|
||||
? MAX_WORD : ltmp <= MIN_WORD ? MIN_WORD : ltmp)
|
||||
|
||||
#endif
|
||||
|
||||
# define GSM_ABS(a) ((a) < 0 ? ((a) == MIN_WORD ? MAX_WORD : -(a)) : (a))
|
||||
|
||||
/* Use these if necessary:
|
||||
|
||||
# define GSM_MULT_R(a, b) gsm_mult_r(a, b)
|
||||
# define GSM_MULT(a, b) gsm_mult(a, b)
|
||||
# define GSM_L_MULT(a, b) gsm_L_mult(a, b)
|
||||
|
||||
# define GSM_L_ADD(a, b) gsm_L_add(a, b)
|
||||
# define GSM_ADD(a, b) gsm_add(a, b)
|
||||
# define GSM_SUB(a, b) gsm_sub(a, b)
|
||||
|
||||
# define GSM_ABS(a) gsm_abs(a)
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
* More prototypes from implementations..
|
||||
*/
|
||||
extern void Gsm_Coder P((
|
||||
struct gsm_state * S,
|
||||
word * s, /* [0..159] samples IN */
|
||||
word * LARc, /* [0..7] LAR coefficients OUT */
|
||||
word * Nc, /* [0..3] LTP lag OUT */
|
||||
word * bc, /* [0..3] coded LTP gain OUT */
|
||||
word * Mc, /* [0..3] RPE grid selection OUT */
|
||||
word * xmaxc,/* [0..3] Coded maximum amplitude OUT */
|
||||
word * xMc /* [13*4] normalized RPE samples OUT */));
|
||||
|
||||
extern void Gsm_Long_Term_Predictor P(( /* 4x for 160 samples */
|
||||
struct gsm_state * S,
|
||||
word * d, /* [0..39] residual signal IN */
|
||||
word * dp, /* [-120..-1] d' IN */
|
||||
word * e, /* [0..40] OUT */
|
||||
word * dpp, /* [0..40] OUT */
|
||||
word * Nc, /* correlation lag OUT */
|
||||
word * bc /* gain factor OUT */));
|
||||
|
||||
extern void Gsm_LPC_Analysis P((
|
||||
struct gsm_state * S,
|
||||
word * s, /* 0..159 signals IN/OUT */
|
||||
word * LARc)); /* 0..7 LARc's OUT */
|
||||
|
||||
extern void Gsm_Preprocess P((
|
||||
struct gsm_state * S,
|
||||
word * s, word * so));
|
||||
|
||||
extern void Gsm_Encoding P((
|
||||
struct gsm_state * S,
|
||||
word * e,
|
||||
word * ep,
|
||||
word * xmaxc,
|
||||
word * Mc,
|
||||
word * xMc));
|
||||
|
||||
extern void Gsm_Short_Term_Analysis_Filter P((
|
||||
struct gsm_state * S,
|
||||
word * LARc, /* coded log area ratio [0..7] IN */
|
||||
word * d /* st res. signal [0..159] IN/OUT */));
|
||||
|
||||
extern void Gsm_Decoder P((
|
||||
struct gsm_state * S,
|
||||
word * LARcr, /* [0..7] IN */
|
||||
word * Ncr, /* [0..3] IN */
|
||||
word * bcr, /* [0..3] IN */
|
||||
word * Mcr, /* [0..3] IN */
|
||||
word * xmaxcr, /* [0..3] IN */
|
||||
word * xMcr, /* [0..13*4] IN */
|
||||
word * s)); /* [0..159] OUT */
|
||||
|
||||
extern void Gsm_Decoding P((
|
||||
struct gsm_state * S,
|
||||
word xmaxcr,
|
||||
word Mcr,
|
||||
word * xMcr, /* [0..12] IN */
|
||||
word * erp)); /* [0..39] OUT */
|
||||
|
||||
extern void Gsm_Long_Term_Synthesis_Filtering P((
|
||||
struct gsm_state* S,
|
||||
word Ncr,
|
||||
word bcr,
|
||||
word * erp, /* [0..39] IN */
|
||||
word * drp)); /* [-120..-1] IN, [0..40] OUT */
|
||||
|
||||
void Gsm_RPE_Decoding P((
|
||||
struct gsm_state *S,
|
||||
word xmaxcr,
|
||||
word Mcr,
|
||||
word * xMcr, /* [0..12], 3 bits IN */
|
||||
word * erp)); /* [0..39] OUT */
|
||||
|
||||
void Gsm_RPE_Encoding P((
|
||||
struct gsm_state * S,
|
||||
word * e, /* -5..-1][0..39][40..44 IN/OUT */
|
||||
word * xmaxc, /* OUT */
|
||||
word * Mc, /* OUT */
|
||||
word * xMc)); /* [0..12] OUT */
|
||||
|
||||
extern void Gsm_Short_Term_Synthesis_Filter P((
|
||||
struct gsm_state * S,
|
||||
word * LARcr, /* log area ratios [0..7] IN */
|
||||
word * drp, /* received d [0...39] IN */
|
||||
word * s)); /* signal s [0..159] OUT */
|
||||
|
||||
extern void Gsm_Update_of_reconstructed_short_time_residual_signal P((
|
||||
word * dpp, /* [0...39] IN */
|
||||
word * ep, /* [0...39] IN */
|
||||
word * dp)); /* [-120...-1] IN/OUT */
|
||||
|
||||
/*
|
||||
* Tables from table.c
|
||||
*/
|
||||
#ifndef GSM_TABLE_C
|
||||
|
||||
extern word gsm_A[8], gsm_B[8], gsm_MIC[8], gsm_MAC[8];
|
||||
extern word gsm_INVA[8];
|
||||
extern word gsm_DLB[4], gsm_QLB[4];
|
||||
extern word gsm_H[11];
|
||||
extern word gsm_NRFAC[8];
|
||||
extern word gsm_FAC[8];
|
||||
|
||||
#endif /* GSM_TABLE_C */
|
||||
|
||||
/*
|
||||
* Debugging
|
||||
*/
|
||||
#ifdef NDEBUG
|
||||
|
||||
# define gsm_debug_words(a, b, c, d) /* nil */
|
||||
# define gsm_debug_longwords(a, b, c, d) /* nil */
|
||||
# define gsm_debug_word(a, b) /* nil */
|
||||
# define gsm_debug_longword(a, b) /* nil */
|
||||
|
||||
#else /* !NDEBUG => DEBUG */
|
||||
|
||||
extern void gsm_debug_words P((char * name, int, int, word *));
|
||||
extern void gsm_debug_longwords P((char * name, int, int, longword *));
|
||||
extern void gsm_debug_longword P((char * name, longword));
|
||||
extern void gsm_debug_word P((char * name, word));
|
||||
|
||||
#endif /* !NDEBUG */
|
||||
|
||||
#include "unproto.h"
|
||||
|
||||
#endif /* PRIVATE_H */
|
65
utils/iaxclient/lib/gsm/inc/proto.h
Normal file
65
utils/iaxclient/lib/gsm/inc/proto.h
Normal file
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
|
||||
* Universitaet Berlin. See the accompanying file "COPYRIGHT" for
|
||||
* details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*$Header$*/
|
||||
|
||||
#ifndef PROTO_H
|
||||
#define PROTO_H
|
||||
|
||||
#if __cplusplus
|
||||
# define NeedFunctionPrototypes 1
|
||||
#endif
|
||||
|
||||
#if __STDC__
|
||||
# define NeedFunctionPrototypes 1
|
||||
#endif
|
||||
|
||||
#ifdef _NO_PROTO
|
||||
# undef NeedFunctionPrototypes
|
||||
#endif
|
||||
|
||||
#undef P /* gnu stdio.h actually defines this... */
|
||||
#undef P0
|
||||
#undef P1
|
||||
#undef P2
|
||||
#undef P3
|
||||
#undef P4
|
||||
#undef P5
|
||||
#undef P6
|
||||
#undef P7
|
||||
#undef P8
|
||||
|
||||
#if NeedFunctionPrototypes
|
||||
|
||||
# define P( protos ) protos
|
||||
|
||||
# define P0() (void)
|
||||
# define P1(x, a) (a)
|
||||
# define P2(x, a, b) (a, b)
|
||||
# define P3(x, a, b, c) (a, b, c)
|
||||
# define P4(x, a, b, c, d) (a, b, c, d)
|
||||
# define P5(x, a, b, c, d, e) (a, b, c, d, e)
|
||||
# define P6(x, a, b, c, d, e, f) (a, b, c, d, e, f)
|
||||
# define P7(x, a, b, c, d, e, f, g) (a, b, c, d, e, f, g)
|
||||
# define P8(x, a, b, c, d, e, f, g, h) (a, b, c, d, e, f, g, h)
|
||||
|
||||
#else /* !NeedFunctionPrototypes */
|
||||
|
||||
# define P( protos ) ( /* protos */ )
|
||||
|
||||
# define P0() ()
|
||||
# define P1(x, a) x a;
|
||||
# define P2(x, a, b) x a; b;
|
||||
# define P3(x, a, b, c) x a; b; c;
|
||||
# define P4(x, a, b, c, d) x a; b; c; d;
|
||||
# define P5(x, a, b, c, d, e) x a; b; c; d; e;
|
||||
# define P6(x, a, b, c, d, e, f) x a; b; c; d; e; f;
|
||||
# define P7(x, a, b, c, d, e, f, g) x a; b; c; d; e; f; g;
|
||||
# define P8(x, a, b, c, d, e, f, g, h) x a; b; c; d; e; f; g; h;
|
||||
|
||||
#endif /* !NeedFunctionPrototypes */
|
||||
|
||||
#endif /* PROTO_H */
|
23
utils/iaxclient/lib/gsm/inc/unproto.h
Normal file
23
utils/iaxclient/lib/gsm/inc/unproto.h
Normal file
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
|
||||
* Universitaet Berlin. See the accompanying file "COPYRIGHT" for
|
||||
* details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*$Header$*/
|
||||
|
||||
#ifdef PROTO_H /* sic */
|
||||
#undef PROTO_H
|
||||
|
||||
#undef P
|
||||
#undef P0
|
||||
#undef P1
|
||||
#undef P2
|
||||
#undef P3
|
||||
#undef P4
|
||||
#undef P5
|
||||
#undef P6
|
||||
#undef P7
|
||||
#undef P8
|
||||
|
||||
#endif /* PROTO_H */
|
65
utils/iaxclient/lib/gsm/libgsm.prj
Normal file
65
utils/iaxclient/lib/gsm/libgsm.prj
Normal file
|
@ -0,0 +1,65 @@
|
|||
; Wedit project file. Syntax: Name = value
|
||||
[libgsm]
|
||||
PrjFiles=18
|
||||
File1=SRC\TABLE.C
|
||||
File2=SRC\SHORT_TERM.C
|
||||
File3=SRC\RPE.C
|
||||
File4=SRC\PREPROCESS.C
|
||||
File5=SRC\LPC.C
|
||||
File6=SRC\LONG_TERM.C
|
||||
File7=SRC\GSM_PRINT.C
|
||||
File8=SRC\GSM_OPTION.C
|
||||
File9=SRC\GSM_IMPLODE.C
|
||||
File10=SRC\GSM_EXPLODE.C
|
||||
File11=SRC\GSM_ENCODE.C
|
||||
File12=SRC\GSM_DESTROY.C
|
||||
File13=SRC\GSM_DECODE.C
|
||||
File14=SRC\GSM_CREATE.C
|
||||
File15=SRC\DECODE.C
|
||||
File16=SRC\DEBUG.C
|
||||
File17=SRC\CODE.C
|
||||
File18=SRC\ADD.C
|
||||
UserCount=1
|
||||
User1=ADMINISTRATOR
|
||||
CmsDirectory=Z:\utils\tools\IAX\DLL\gsm\CMS
|
||||
PutOptions=4
|
||||
GetOptions=0
|
||||
FileOptions=0
|
||||
LockOptions=1
|
||||
UsersOptions=1
|
||||
ProjectFlags=0
|
||||
ExtraCmsFilesCount=0
|
||||
File19=SRC\LPC.C
|
||||
File20=SRC\PREPROCESS.C
|
||||
File21=SRC\RPE.C
|
||||
File22=SRC\SHORT_TERM.C
|
||||
File23=SRC\TABLE.C
|
||||
Frame=0 108 765 642
|
||||
StatusBar=0,0,0,0
|
||||
Name=libgsm
|
||||
CurrentFile=
|
||||
OpenFiles=0
|
||||
ProjectPath=Z:\UTILS\TOOLS\IAX\DLL\GSM
|
||||
SourcesDir=Z:\utils\tools\IAX\DLL\gsm
|
||||
Defines=
|
||||
Includes=c:\programme\lcc\include;z:\utils\tools\iax\dll\gsm\inc
|
||||
Libraries=
|
||||
LinkerArgs=
|
||||
ProjectTime=1218
|
||||
MakeName=c:\programme\lcc\bin\make.exe
|
||||
MakeDir=Z:\utils\tools\IAX\DLL\gsm\lcc
|
||||
Exe=z:\utils\tools\iax\dll\gsm\lcc\libgsm.lib
|
||||
DebuggerArguments=
|
||||
DbgExeName=z:\utils\tools\iax\dll\gsm\lcc\libgsm.lib
|
||||
DbgDir=z:\utils\tools\iax\dll\gsm\lcc
|
||||
CompilerFlags=1032
|
||||
FortranFlags=0
|
||||
EiffelFlags=0
|
||||
Useframework=0
|
||||
NumberOfBreakpoints=0
|
||||
ErrorFile=
|
||||
NrOfFileProcessors=0
|
||||
UserName=ADMINISTRATOR
|
||||
OpenFile1="z:\utils\tools\iax\dll\gsm\src\table.c" 18 146 204 820 391
|
||||
OpenFile2="c:\test\ax\gsm\src\code.c" 12 181 233 877 610
|
||||
File24=C:\PROGRAMME\LCC\LIB\LIBC.LIB
|
37
utils/iaxclient/lib/gsm/readme
Normal file
37
utils/iaxclient/lib/gsm/readme
Normal file
|
@ -0,0 +1,37 @@
|
|||
|
||||
GSM 06.10 13 kbit/s RPE/LTP speech compression available
|
||||
--------------------------------------------------------
|
||||
|
||||
The Communications and Operating Systems Research Group (KBS) at the
|
||||
Technische Universitaet Berlin is currently working on a set of
|
||||
UNIX-based tools for computer-mediated telecooperation that will be
|
||||
made freely available.
|
||||
|
||||
As part of this effort we are publishing an implementation of the
|
||||
European GSM 06.10 provisional standard for full-rate speech
|
||||
transcoding, prI-ETS 300 036, which uses RPE/LTP (residual pulse
|
||||
excitation/long term prediction) coding at 13 kbit/s.
|
||||
|
||||
GSM 06.10 compresses frames of 160 13-bit samples (8 kHz sampling
|
||||
rate, i.e. a frame rate of 50 Hz) into 260 bits; for compatibility
|
||||
with typical UNIX applications, our implementation turns frames of 160
|
||||
16-bit linear samples into 33-byte frames (1650 Bytes/s).
|
||||
The quality of the algorithm is good enough for reliable speaker
|
||||
recognition; even music often survives transcoding in recognizable
|
||||
form (given the bandwidth limitations of 8 kHz sampling rate).
|
||||
|
||||
The interfaces offered are a front end modelled after compress(1), and
|
||||
a library API. Compression and decompression run faster than realtime
|
||||
on most SPARCstations. The implementation has been verified against the
|
||||
ETSI standard test patterns.
|
||||
|
||||
Jutta Degener (jutta@cs.tu-berlin.de)
|
||||
Carsten Bormann (cabo@cs.tu-berlin.de)
|
||||
|
||||
Communications and Operating Systems Research Group, TU Berlin
|
||||
Fax: +49.30.31425156, Phone: +49.30.31424315
|
||||
|
||||
--
|
||||
Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
|
||||
Universitaet Berlin. See the accompanying file "COPYRIGHT" for
|
||||
details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
|
235
utils/iaxclient/lib/gsm/src/add.c
Normal file
235
utils/iaxclient/lib/gsm/src/add.c
Normal file
|
@ -0,0 +1,235 @@
|
|||
/*
|
||||
* Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
|
||||
* Universitaet Berlin. See the accompanying file "COPYRIGHT" for
|
||||
* details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Header$ */
|
||||
|
||||
/*
|
||||
* See private.h for the more commonly used macro versions.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "private.h"
|
||||
#include "gsm.h"
|
||||
#include "proto.h"
|
||||
|
||||
#define saturate(x) \
|
||||
((x) < MIN_WORD ? MIN_WORD : (x) > MAX_WORD ? MAX_WORD: (x))
|
||||
|
||||
word gsm_add P2((a,b), word a, word b)
|
||||
{
|
||||
longword sum = (longword)a + (longword)b;
|
||||
return (word) saturate(sum);
|
||||
}
|
||||
|
||||
word gsm_sub P2((a,b), word a, word b)
|
||||
{
|
||||
longword diff = (longword)a - (longword)b;
|
||||
return (word) saturate(diff);
|
||||
}
|
||||
|
||||
word gsm_mult P2((a,b), word a, word b)
|
||||
{
|
||||
if (a == MIN_WORD && b == MIN_WORD) return MAX_WORD;
|
||||
else return SASR( (longword)a * (longword)b, 15 );
|
||||
}
|
||||
|
||||
word gsm_mult_r P2((a,b), word a, word b)
|
||||
{
|
||||
if (b == MIN_WORD && a == MIN_WORD) return MAX_WORD;
|
||||
else {
|
||||
longword prod = (longword)a * (longword)b + 16384;
|
||||
prod >>= 15;
|
||||
return prod & 0xFFFF;
|
||||
}
|
||||
}
|
||||
|
||||
word gsm_abs P1((a), word a)
|
||||
{
|
||||
return a < 0 ? (a == MIN_WORD ? MAX_WORD : -a) : a;
|
||||
}
|
||||
|
||||
longword gsm_L_mult P2((a,b),word a, word b)
|
||||
{
|
||||
assert( a != MIN_WORD || b != MIN_WORD );
|
||||
return ((longword)a * (longword)b) << 1;
|
||||
}
|
||||
|
||||
longword gsm_L_add P2((a,b), longword a, longword b)
|
||||
{
|
||||
if (a < 0) {
|
||||
if (b >= 0) return a + b;
|
||||
else {
|
||||
ulongword A = (ulongword)-(a + 1) + (ulongword)-(b + 1);
|
||||
return A >= MAX_LONGWORD ? MIN_LONGWORD :-(longword)A-2;
|
||||
}
|
||||
}
|
||||
else if (b <= 0) return a + b;
|
||||
else {
|
||||
ulongword A = (ulongword)a + (ulongword)b;
|
||||
return A > MAX_LONGWORD ? MAX_LONGWORD : A;
|
||||
}
|
||||
}
|
||||
|
||||
longword gsm_L_sub P2((a,b), longword a, longword b)
|
||||
{
|
||||
if (a >= 0) {
|
||||
if (b >= 0) return a - b;
|
||||
else {
|
||||
/* a>=0, b<0 */
|
||||
|
||||
ulongword A = (ulongword)a + -(b + 1);
|
||||
return A >= MAX_LONGWORD ? MAX_LONGWORD : (A + 1);
|
||||
}
|
||||
}
|
||||
else if (b <= 0) return a - b;
|
||||
else {
|
||||
/* a<0, b>0 */
|
||||
|
||||
ulongword A = (ulongword)-(a + 1) + b;
|
||||
return A >= MAX_LONGWORD ? MIN_LONGWORD : -(longword)A - 1;
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned char const bitoff[ 256 ] = {
|
||||
8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
word gsm_norm P1((a), longword a )
|
||||
/*
|
||||
* the number of left shifts needed to normalize the 32 bit
|
||||
* variable L_var1 for positive values on the interval
|
||||
*
|
||||
* with minimum of
|
||||
* minimum of 1073741824 (01000000000000000000000000000000) and
|
||||
* maximum of 2147483647 (01111111111111111111111111111111)
|
||||
*
|
||||
*
|
||||
* and for negative values on the interval with
|
||||
* minimum of -2147483648 (-10000000000000000000000000000000) and
|
||||
* maximum of -1073741824 ( -1000000000000000000000000000000).
|
||||
*
|
||||
* in order to normalize the result, the following
|
||||
* operation must be done: L_norm_var1 = L_var1 << norm( L_var1 );
|
||||
*
|
||||
* (That's 'ffs', only from the left, not the right..)
|
||||
*/
|
||||
{
|
||||
assert(a != 0);
|
||||
|
||||
if (a < 0) {
|
||||
if (a <= -1073741824) return 0;
|
||||
a = ~a;
|
||||
}
|
||||
|
||||
return a & 0xffff0000
|
||||
? ( a & 0xff000000
|
||||
? -1 + bitoff[ 0xFF & (a >> 24) ]
|
||||
: 7 + bitoff[ 0xFF & (a >> 16) ] )
|
||||
: ( a & 0xff00
|
||||
? 15 + bitoff[ 0xFF & (a >> 8) ]
|
||||
: 23 + bitoff[ 0xFF & a ] );
|
||||
}
|
||||
|
||||
longword gsm_L_asl P2((a,n), longword a, int n)
|
||||
{
|
||||
if (n >= 32) return 0;
|
||||
if (n <= -32) return -(a < 0);
|
||||
if (n < 0) return gsm_L_asr(a, -n);
|
||||
return a << n;
|
||||
}
|
||||
|
||||
word gsm_asl P2((a,n), word a, int n)
|
||||
{
|
||||
if (n >= 16) return 0;
|
||||
if (n <= -16) return -(a < 0);
|
||||
if (n < 0) return gsm_asr(a, -n);
|
||||
return a << n;
|
||||
}
|
||||
|
||||
longword gsm_L_asr P2((a,n), longword a, int n)
|
||||
{
|
||||
if (n >= 32) return -(a < 0);
|
||||
if (n <= -32) return 0;
|
||||
if (n < 0) return a << -n;
|
||||
|
||||
# ifdef SASR
|
||||
return a >> n;
|
||||
# else
|
||||
if (a >= 0) return a >> n;
|
||||
else return -(longword)( -(ulongword)a >> n );
|
||||
# endif
|
||||
}
|
||||
|
||||
word gsm_asr P2((a,n), word a, int n)
|
||||
{
|
||||
if (n >= 16) return -(a < 0);
|
||||
if (n <= -16) return 0;
|
||||
if (n < 0) return a << -n;
|
||||
|
||||
# ifdef SASR
|
||||
return a >> n;
|
||||
# else
|
||||
if (a >= 0) return a >> n;
|
||||
else return -(word)( -(uword)a >> n );
|
||||
# endif
|
||||
}
|
||||
|
||||
/*
|
||||
* (From p. 46, end of section 4.2.5)
|
||||
*
|
||||
* NOTE: The following lines gives [sic] one correct implementation
|
||||
* of the div(num, denum) arithmetic operation. Compute div
|
||||
* which is the integer division of num by denum: with denum
|
||||
* >= num > 0
|
||||
*/
|
||||
|
||||
word gsm_div P2((num,denum), word num, word denum)
|
||||
{
|
||||
longword L_num = num;
|
||||
longword L_denum = denum;
|
||||
word div = 0;
|
||||
int k = 15;
|
||||
|
||||
/* The parameter num sometimes becomes zero.
|
||||
* Although this is explicitly guarded against in 4.2.5,
|
||||
* we assume that the result should then be zero as well.
|
||||
*/
|
||||
|
||||
/* assert(num != 0); */
|
||||
|
||||
assert(num >= 0 && denum >= num);
|
||||
if (num == 0)
|
||||
return 0;
|
||||
|
||||
while (k--) {
|
||||
div <<= 1;
|
||||
L_num <<= 1;
|
||||
|
||||
if (L_num >= L_denum) {
|
||||
L_num -= L_denum;
|
||||
div++;
|
||||
}
|
||||
}
|
||||
|
||||
return div;
|
||||
}
|
100
utils/iaxclient/lib/gsm/src/code.c
Normal file
100
utils/iaxclient/lib/gsm/src/code.c
Normal file
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
* Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
|
||||
* Universitaet Berlin. See the accompanying file "COPYRIGHT" for
|
||||
* details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Header$ */
|
||||
|
||||
#include "config.h"
|
||||
|
||||
|
||||
//#ifdef HAS_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
//#else
|
||||
# include "proto.h"
|
||||
# include "string.h"
|
||||
//extern char * memcpy P((char *, char *, int));
|
||||
//#endif
|
||||
|
||||
#include "private.h"
|
||||
#include "gsm.h"
|
||||
#include "proto.h"
|
||||
|
||||
/*
|
||||
* 4.2 FIXED POINT IMPLEMENTATION OF THE RPE-LTP CODER
|
||||
*/
|
||||
|
||||
void Gsm_Coder P8((S,s,LARc,Nc,bc,Mc,xmaxc,xMc),
|
||||
|
||||
struct gsm_state * S,
|
||||
|
||||
word * s, /* [0..159] samples IN */
|
||||
|
||||
/*
|
||||
* The RPE-LTD coder works on a frame by frame basis. The length of
|
||||
* the frame is equal to 160 samples. Some computations are done
|
||||
* once per frame to produce at the output of the coder the
|
||||
* LARc[1..8] parameters which are the coded LAR coefficients and
|
||||
* also to realize the inverse filtering operation for the entire
|
||||
* frame (160 samples of signal d[0..159]). These parts produce at
|
||||
* the output of the coder:
|
||||
*/
|
||||
|
||||
word * LARc, /* [0..7] LAR coefficients OUT */
|
||||
|
||||
/*
|
||||
* Procedure 4.2.11 to 4.2.18 are to be executed four times per
|
||||
* frame. That means once for each sub-segment RPE-LTP analysis of
|
||||
* 40 samples. These parts produce at the output of the coder:
|
||||
*/
|
||||
|
||||
word * Nc, /* [0..3] LTP lag OUT */
|
||||
word * bc, /* [0..3] coded LTP gain OUT */
|
||||
word * Mc, /* [0..3] RPE grid selection OUT */
|
||||
word * xmaxc,/* [0..3] Coded maximum amplitude OUT */
|
||||
word * xMc /* [13*4] normalized RPE samples OUT */
|
||||
)
|
||||
{
|
||||
int k;
|
||||
word * dp = S->dp0 + 120; /* [ -120...-1 ] */
|
||||
word * dpp = dp; /* [ 0...39 ] */
|
||||
|
||||
static word e[50];
|
||||
|
||||
word so[160];
|
||||
|
||||
Gsm_Preprocess (S, s, so);
|
||||
Gsm_LPC_Analysis (S, so, LARc);
|
||||
Gsm_Short_Term_Analysis_Filter (S, LARc, so);
|
||||
|
||||
for (k = 0; k <= 3; k++, xMc += 13) {
|
||||
|
||||
Gsm_Long_Term_Predictor ( S,
|
||||
so+k*40, /* d [0..39] IN */
|
||||
dp, /* dp [-120..-1] IN */
|
||||
e + 5, /* e [0..39] OUT */
|
||||
dpp, /* dpp [0..39] OUT */
|
||||
Nc++,
|
||||
bc++);
|
||||
|
||||
Gsm_RPE_Encoding ( S,
|
||||
e + 5, /* e ][0..39][ IN/OUT */
|
||||
xmaxc++, Mc++, xMc );
|
||||
/*
|
||||
* Gsm_Update_of_reconstructed_short_time_residual_signal
|
||||
* ( dpp, e + 5, dp );
|
||||
*/
|
||||
|
||||
{ register int i;
|
||||
register longword ltmp;
|
||||
for (i = 0; i <= 39; i++)
|
||||
dp[ i ] = GSM_ADD( e[5 + i], dpp[i] );
|
||||
}
|
||||
dp += 40;
|
||||
dpp += 40;
|
||||
|
||||
}
|
||||
(void)memcpy( (char *)S->dp0, (char *)(S->dp0 + 160),
|
||||
120 * sizeof(*S->dp0) );
|
||||
}
|
76
utils/iaxclient/lib/gsm/src/debug.c
Normal file
76
utils/iaxclient/lib/gsm/src/debug.c
Normal file
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
|
||||
* Universitaet Berlin. See the accompanying file "COPYRIGHT" for
|
||||
* details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Header$ */
|
||||
|
||||
#include "private.h"
|
||||
|
||||
#ifndef NDEBUG
|
||||
|
||||
/* If NDEBUG _is_ defined and no debugging should be performed,
|
||||
* calls to functions in this module are #defined to nothing
|
||||
* in private.h.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "proto.h"
|
||||
|
||||
void gsm_debug_words P4( (name, from, to, ptr),
|
||||
char * name,
|
||||
int from,
|
||||
int to,
|
||||
word * ptr)
|
||||
{
|
||||
int nprinted = 0;
|
||||
|
||||
fprintf( stderr, "%s [%d .. %d]: ", name, from, to );
|
||||
while (from <= to) {
|
||||
fprintf(stderr, "%d ", ptr[ from ] );
|
||||
from++;
|
||||
if (nprinted++ >= 7) {
|
||||
nprinted = 0;
|
||||
if (from < to) putc('\n', stderr);
|
||||
}
|
||||
}
|
||||
putc('\n', stderr);
|
||||
}
|
||||
|
||||
void gsm_debug_longwords P4( (name, from, to, ptr),
|
||||
char * name,
|
||||
int from,
|
||||
int to,
|
||||
longword * ptr)
|
||||
{
|
||||
int nprinted = 0;
|
||||
|
||||
fprintf( stderr, "%s [%d .. %d]: ", name, from, to );
|
||||
while (from <= to) {
|
||||
|
||||
fprintf(stderr, "%d ", ptr[ from ] );
|
||||
from++;
|
||||
if (nprinted++ >= 7) {
|
||||
nprinted = 0;
|
||||
if (from < to) putc('\n', stderr);
|
||||
}
|
||||
}
|
||||
putc('\n', stderr);
|
||||
}
|
||||
|
||||
void gsm_debug_longword P2( (name, value),
|
||||
char * name,
|
||||
longword value )
|
||||
{
|
||||
fprintf(stderr, "%s: %d\n", name, (long)value );
|
||||
}
|
||||
|
||||
void gsm_debug_word P2( (name, value),
|
||||
char * name,
|
||||
word value )
|
||||
{
|
||||
fprintf(stderr, "%s: %d\n", name, (long)value);
|
||||
}
|
||||
|
||||
#endif
|
63
utils/iaxclient/lib/gsm/src/decode.c
Normal file
63
utils/iaxclient/lib/gsm/src/decode.c
Normal file
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
|
||||
* Universitaet Berlin. See the accompanying file "COPYRIGHT" for
|
||||
* details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Header$ */
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "private.h"
|
||||
#include "gsm.h"
|
||||
#include "proto.h"
|
||||
|
||||
/*
|
||||
* 4.3 FIXED POINT IMPLEMENTATION OF THE RPE-LTP DECODER
|
||||
*/
|
||||
|
||||
static void Postprocessing P2((S,s),
|
||||
struct gsm_state * S,
|
||||
register word * s)
|
||||
{
|
||||
register int k;
|
||||
register word msr = S->msr;
|
||||
register longword ltmp; /* for GSM_ADD */
|
||||
register word tmp;
|
||||
|
||||
for (k = 160; k--; s++) {
|
||||
tmp = GSM_MULT_R( msr, 28180 );
|
||||
msr = GSM_ADD(*s, tmp); /* Deemphasis */
|
||||
*s = GSM_ADD(msr, msr) & 0xFFF8; /* Truncation & Upscaling */
|
||||
}
|
||||
S->msr = msr;
|
||||
}
|
||||
|
||||
void Gsm_Decoder P8((S,LARcr, Ncr,bcr,Mcr,xmaxcr,xMcr,s),
|
||||
struct gsm_state * S,
|
||||
|
||||
word * LARcr, /* [0..7] IN */
|
||||
|
||||
word * Ncr, /* [0..3] IN */
|
||||
word * bcr, /* [0..3] IN */
|
||||
word * Mcr, /* [0..3] IN */
|
||||
word * xmaxcr, /* [0..3] IN */
|
||||
word * xMcr, /* [0..13*4] IN */
|
||||
|
||||
word * s) /* [0..159] OUT */
|
||||
{
|
||||
int j, k;
|
||||
word erp[40], wt[160];
|
||||
word * drp = S->dp0 + 120;
|
||||
|
||||
for (j=0; j <= 3; j++, xmaxcr++, bcr++, Ncr++, Mcr++, xMcr += 13) {
|
||||
|
||||
Gsm_RPE_Decoding( S, *xmaxcr, *Mcr, xMcr, erp );
|
||||
Gsm_Long_Term_Synthesis_Filtering( S, *Ncr, *bcr, erp, drp );
|
||||
|
||||
for (k = 0; k <= 39; k++) wt[ j * 40 + k ] = drp[ k ];
|
||||
}
|
||||
|
||||
Gsm_Short_Term_Synthesis_Filter( S, LARcr, wt, s );
|
||||
Postprocessing(S, s);
|
||||
}
|
45
utils/iaxclient/lib/gsm/src/gsm_create.c
Normal file
45
utils/iaxclient/lib/gsm/src/gsm_create.c
Normal file
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
|
||||
* Universitaet Berlin. See the accompanying file "COPYRIGHT" for
|
||||
* details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
static char const ident[] = "$Header$";
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifdef HAS_STRING_H
|
||||
#include <string.h>
|
||||
#else
|
||||
# include "proto.h"
|
||||
extern char * memset P((char *, int, int));
|
||||
#endif
|
||||
|
||||
#ifdef HAS_STDLIB_H
|
||||
# include <stdlib.h>
|
||||
#else
|
||||
# ifdef HAS_MALLOC_H
|
||||
# include <malloc.h>
|
||||
# else
|
||||
extern char * malloc();
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "gsm.h"
|
||||
#include "private.h"
|
||||
#include "proto.h"
|
||||
|
||||
gsm gsm_create P0()
|
||||
{
|
||||
gsm r;
|
||||
|
||||
r = (gsm)malloc(sizeof(struct gsm_state));
|
||||
if (!r) return r;
|
||||
|
||||
memset((char *)r, 0, sizeof(*r));
|
||||
r->nrp = 40;
|
||||
|
||||
return r;
|
||||
}
|
361
utils/iaxclient/lib/gsm/src/gsm_decode.c
Normal file
361
utils/iaxclient/lib/gsm/src/gsm_decode.c
Normal file
|
@ -0,0 +1,361 @@
|
|||
/*
|
||||
* Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
|
||||
* Universitaet Berlin. See the accompanying file "COPYRIGHT" for
|
||||
* details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Header$ */
|
||||
|
||||
#include "private.h"
|
||||
|
||||
#include "gsm.h"
|
||||
#include "proto.h"
|
||||
|
||||
int gsm_decode P3((s, c, target), gsm s, gsm_byte * c, gsm_signal * target)
|
||||
{
|
||||
word LARc[8], Nc[4], Mc[4], bc[4], xmaxc[4], xmc[13*4];
|
||||
|
||||
#ifdef WAV49
|
||||
if (s->wav_fmt) {
|
||||
|
||||
uword sr = 0;
|
||||
|
||||
s->frame_index = !s->frame_index;
|
||||
if (s->frame_index) {
|
||||
|
||||
sr = *c++;
|
||||
LARc[0] = sr & 0x3f; sr >>= 6;
|
||||
sr |= (uword)*c++ << 2;
|
||||
LARc[1] = sr & 0x3f; sr >>= 6;
|
||||
sr |= (uword)*c++ << 4;
|
||||
LARc[2] = sr & 0x1f; sr >>= 5;
|
||||
LARc[3] = sr & 0x1f; sr >>= 5;
|
||||
sr |= (uword)*c++ << 2;
|
||||
LARc[4] = sr & 0xf; sr >>= 4;
|
||||
LARc[5] = sr & 0xf; sr >>= 4;
|
||||
sr |= (uword)*c++ << 2; /* 5 */
|
||||
LARc[6] = sr & 0x7; sr >>= 3;
|
||||
LARc[7] = sr & 0x7; sr >>= 3;
|
||||
sr |= (uword)*c++ << 4;
|
||||
Nc[0] = sr & 0x7f; sr >>= 7;
|
||||
bc[0] = sr & 0x3; sr >>= 2;
|
||||
Mc[0] = sr & 0x3; sr >>= 2;
|
||||
sr |= (uword)*c++ << 1;
|
||||
xmaxc[0] = sr & 0x3f; sr >>= 6;
|
||||
xmc[0] = sr & 0x7; sr >>= 3;
|
||||
sr = *c++;
|
||||
xmc[1] = sr & 0x7; sr >>= 3;
|
||||
xmc[2] = sr & 0x7; sr >>= 3;
|
||||
sr |= (uword)*c++ << 2;
|
||||
xmc[3] = sr & 0x7; sr >>= 3;
|
||||
xmc[4] = sr & 0x7; sr >>= 3;
|
||||
xmc[5] = sr & 0x7; sr >>= 3;
|
||||
sr |= (uword)*c++ << 1; /* 10 */
|
||||
xmc[6] = sr & 0x7; sr >>= 3;
|
||||
xmc[7] = sr & 0x7; sr >>= 3;
|
||||
xmc[8] = sr & 0x7; sr >>= 3;
|
||||
sr = *c++;
|
||||
xmc[9] = sr & 0x7; sr >>= 3;
|
||||
xmc[10] = sr & 0x7; sr >>= 3;
|
||||
sr |= (uword)*c++ << 2;
|
||||
xmc[11] = sr & 0x7; sr >>= 3;
|
||||
xmc[12] = sr & 0x7; sr >>= 3;
|
||||
sr |= (uword)*c++ << 4;
|
||||
Nc[1] = sr & 0x7f; sr >>= 7;
|
||||
bc[1] = sr & 0x3; sr >>= 2;
|
||||
Mc[1] = sr & 0x3; sr >>= 2;
|
||||
sr |= (uword)*c++ << 1;
|
||||
xmaxc[1] = sr & 0x3f; sr >>= 6;
|
||||
xmc[13] = sr & 0x7; sr >>= 3;
|
||||
sr = *c++; /* 15 */
|
||||
xmc[14] = sr & 0x7; sr >>= 3;
|
||||
xmc[15] = sr & 0x7; sr >>= 3;
|
||||
sr |= (uword)*c++ << 2;
|
||||
xmc[16] = sr & 0x7; sr >>= 3;
|
||||
xmc[17] = sr & 0x7; sr >>= 3;
|
||||
xmc[18] = sr & 0x7; sr >>= 3;
|
||||
sr |= (uword)*c++ << 1;
|
||||
xmc[19] = sr & 0x7; sr >>= 3;
|
||||
xmc[20] = sr & 0x7; sr >>= 3;
|
||||
xmc[21] = sr & 0x7; sr >>= 3;
|
||||
sr = *c++;
|
||||
xmc[22] = sr & 0x7; sr >>= 3;
|
||||
xmc[23] = sr & 0x7; sr >>= 3;
|
||||
sr |= (uword)*c++ << 2;
|
||||
xmc[24] = sr & 0x7; sr >>= 3;
|
||||
xmc[25] = sr & 0x7; sr >>= 3;
|
||||
sr |= (uword)*c++ << 4; /* 20 */
|
||||
Nc[2] = sr & 0x7f; sr >>= 7;
|
||||
bc[2] = sr & 0x3; sr >>= 2;
|
||||
Mc[2] = sr & 0x3; sr >>= 2;
|
||||
sr |= (uword)*c++ << 1;
|
||||
xmaxc[2] = sr & 0x3f; sr >>= 6;
|
||||
xmc[26] = sr & 0x7; sr >>= 3;
|
||||
sr = *c++;
|
||||
xmc[27] = sr & 0x7; sr >>= 3;
|
||||
xmc[28] = sr & 0x7; sr >>= 3;
|
||||
sr |= (uword)*c++ << 2;
|
||||
xmc[29] = sr & 0x7; sr >>= 3;
|
||||
xmc[30] = sr & 0x7; sr >>= 3;
|
||||
xmc[31] = sr & 0x7; sr >>= 3;
|
||||
sr |= (uword)*c++ << 1;
|
||||
xmc[32] = sr & 0x7; sr >>= 3;
|
||||
xmc[33] = sr & 0x7; sr >>= 3;
|
||||
xmc[34] = sr & 0x7; sr >>= 3;
|
||||
sr = *c++; /* 25 */
|
||||
xmc[35] = sr & 0x7; sr >>= 3;
|
||||
xmc[36] = sr & 0x7; sr >>= 3;
|
||||
sr |= (uword)*c++ << 2;
|
||||
xmc[37] = sr & 0x7; sr >>= 3;
|
||||
xmc[38] = sr & 0x7; sr >>= 3;
|
||||
sr |= (uword)*c++ << 4;
|
||||
Nc[3] = sr & 0x7f; sr >>= 7;
|
||||
bc[3] = sr & 0x3; sr >>= 2;
|
||||
Mc[3] = sr & 0x3; sr >>= 2;
|
||||
sr |= (uword)*c++ << 1;
|
||||
xmaxc[3] = sr & 0x3f; sr >>= 6;
|
||||
xmc[39] = sr & 0x7; sr >>= 3;
|
||||
sr = *c++;
|
||||
xmc[40] = sr & 0x7; sr >>= 3;
|
||||
xmc[41] = sr & 0x7; sr >>= 3;
|
||||
sr |= (uword)*c++ << 2; /* 30 */
|
||||
xmc[42] = sr & 0x7; sr >>= 3;
|
||||
xmc[43] = sr & 0x7; sr >>= 3;
|
||||
xmc[44] = sr & 0x7; sr >>= 3;
|
||||
sr |= (uword)*c++ << 1;
|
||||
xmc[45] = sr & 0x7; sr >>= 3;
|
||||
xmc[46] = sr & 0x7; sr >>= 3;
|
||||
xmc[47] = sr & 0x7; sr >>= 3;
|
||||
sr = *c++;
|
||||
xmc[48] = sr & 0x7; sr >>= 3;
|
||||
xmc[49] = sr & 0x7; sr >>= 3;
|
||||
sr |= (uword)*c++ << 2;
|
||||
xmc[50] = sr & 0x7; sr >>= 3;
|
||||
xmc[51] = sr & 0x7; sr >>= 3;
|
||||
|
||||
s->frame_chain = sr & 0xf;
|
||||
}
|
||||
else {
|
||||
sr = s->frame_chain;
|
||||
sr |= (uword)*c++ << 4; /* 1 */
|
||||
LARc[0] = sr & 0x3f; sr >>= 6;
|
||||
LARc[1] = sr & 0x3f; sr >>= 6;
|
||||
sr = *c++;
|
||||
LARc[2] = sr & 0x1f; sr >>= 5;
|
||||
sr |= (uword)*c++ << 3;
|
||||
LARc[3] = sr & 0x1f; sr >>= 5;
|
||||
LARc[4] = sr & 0xf; sr >>= 4;
|
||||
sr |= (uword)*c++ << 2;
|
||||
LARc[5] = sr & 0xf; sr >>= 4;
|
||||
LARc[6] = sr & 0x7; sr >>= 3;
|
||||
LARc[7] = sr & 0x7; sr >>= 3;
|
||||
sr = *c++; /* 5 */
|
||||
Nc[0] = sr & 0x7f; sr >>= 7;
|
||||
sr |= (uword)*c++ << 1;
|
||||
bc[0] = sr & 0x3; sr >>= 2;
|
||||
Mc[0] = sr & 0x3; sr >>= 2;
|
||||
sr |= (uword)*c++ << 5;
|
||||
xmaxc[0] = sr & 0x3f; sr >>= 6;
|
||||
xmc[0] = sr & 0x7; sr >>= 3;
|
||||
xmc[1] = sr & 0x7; sr >>= 3;
|
||||
sr |= (uword)*c++ << 1;
|
||||
xmc[2] = sr & 0x7; sr >>= 3;
|
||||
xmc[3] = sr & 0x7; sr >>= 3;
|
||||
xmc[4] = sr & 0x7; sr >>= 3;
|
||||
sr = *c++;
|
||||
xmc[5] = sr & 0x7; sr >>= 3;
|
||||
xmc[6] = sr & 0x7; sr >>= 3;
|
||||
sr |= (uword)*c++ << 2; /* 10 */
|
||||
xmc[7] = sr & 0x7; sr >>= 3;
|
||||
xmc[8] = sr & 0x7; sr >>= 3;
|
||||
xmc[9] = sr & 0x7; sr >>= 3;
|
||||
sr |= (uword)*c++ << 1;
|
||||
xmc[10] = sr & 0x7; sr >>= 3;
|
||||
xmc[11] = sr & 0x7; sr >>= 3;
|
||||
xmc[12] = sr & 0x7; sr >>= 3;
|
||||
sr = *c++;
|
||||
Nc[1] = sr & 0x7f; sr >>= 7;
|
||||
sr |= (uword)*c++ << 1;
|
||||
bc[1] = sr & 0x3; sr >>= 2;
|
||||
Mc[1] = sr & 0x3; sr >>= 2;
|
||||
sr |= (uword)*c++ << 5;
|
||||
xmaxc[1] = sr & 0x3f; sr >>= 6;
|
||||
xmc[13] = sr & 0x7; sr >>= 3;
|
||||
xmc[14] = sr & 0x7; sr >>= 3;
|
||||
sr |= (uword)*c++ << 1; /* 15 */
|
||||
xmc[15] = sr & 0x7; sr >>= 3;
|
||||
xmc[16] = sr & 0x7; sr >>= 3;
|
||||
xmc[17] = sr & 0x7; sr >>= 3;
|
||||
sr = *c++;
|
||||
xmc[18] = sr & 0x7; sr >>= 3;
|
||||
xmc[19] = sr & 0x7; sr >>= 3;
|
||||
sr |= (uword)*c++ << 2;
|
||||
xmc[20] = sr & 0x7; sr >>= 3;
|
||||
xmc[21] = sr & 0x7; sr >>= 3;
|
||||
xmc[22] = sr & 0x7; sr >>= 3;
|
||||
sr |= (uword)*c++ << 1;
|
||||
xmc[23] = sr & 0x7; sr >>= 3;
|
||||
xmc[24] = sr & 0x7; sr >>= 3;
|
||||
xmc[25] = sr & 0x7; sr >>= 3;
|
||||
sr = *c++;
|
||||
Nc[2] = sr & 0x7f; sr >>= 7;
|
||||
sr |= (uword)*c++ << 1; /* 20 */
|
||||
bc[2] = sr & 0x3; sr >>= 2;
|
||||
Mc[2] = sr & 0x3; sr >>= 2;
|
||||
sr |= (uword)*c++ << 5;
|
||||
xmaxc[2] = sr & 0x3f; sr >>= 6;
|
||||
xmc[26] = sr & 0x7; sr >>= 3;
|
||||
xmc[27] = sr & 0x7; sr >>= 3;
|
||||
sr |= (uword)*c++ << 1;
|
||||
xmc[28] = sr & 0x7; sr >>= 3;
|
||||
xmc[29] = sr & 0x7; sr >>= 3;
|
||||
xmc[30] = sr & 0x7; sr >>= 3;
|
||||
sr = *c++;
|
||||
xmc[31] = sr & 0x7; sr >>= 3;
|
||||
xmc[32] = sr & 0x7; sr >>= 3;
|
||||
sr |= (uword)*c++ << 2;
|
||||
xmc[33] = sr & 0x7; sr >>= 3;
|
||||
xmc[34] = sr & 0x7; sr >>= 3;
|
||||
xmc[35] = sr & 0x7; sr >>= 3;
|
||||
sr |= (uword)*c++ << 1; /* 25 */
|
||||
xmc[36] = sr & 0x7; sr >>= 3;
|
||||
xmc[37] = sr & 0x7; sr >>= 3;
|
||||
xmc[38] = sr & 0x7; sr >>= 3;
|
||||
sr = *c++;
|
||||
Nc[3] = sr & 0x7f; sr >>= 7;
|
||||
sr |= (uword)*c++ << 1;
|
||||
bc[3] = sr & 0x3; sr >>= 2;
|
||||
Mc[3] = sr & 0x3; sr >>= 2;
|
||||
sr |= (uword)*c++ << 5;
|
||||
xmaxc[3] = sr & 0x3f; sr >>= 6;
|
||||
xmc[39] = sr & 0x7; sr >>= 3;
|
||||
xmc[40] = sr & 0x7; sr >>= 3;
|
||||
sr |= (uword)*c++ << 1;
|
||||
xmc[41] = sr & 0x7; sr >>= 3;
|
||||
xmc[42] = sr & 0x7; sr >>= 3;
|
||||
xmc[43] = sr & 0x7; sr >>= 3;
|
||||
sr = *c++; /* 30 */
|
||||
xmc[44] = sr & 0x7; sr >>= 3;
|
||||
xmc[45] = sr & 0x7; sr >>= 3;
|
||||
sr |= (uword)*c++ << 2;
|
||||
xmc[46] = sr & 0x7; sr >>= 3;
|
||||
xmc[47] = sr & 0x7; sr >>= 3;
|
||||
xmc[48] = sr & 0x7; sr >>= 3;
|
||||
sr |= (uword)*c++ << 1;
|
||||
xmc[49] = sr & 0x7; sr >>= 3;
|
||||
xmc[50] = sr & 0x7; sr >>= 3;
|
||||
xmc[51] = sr & 0x7; sr >>= 3;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
/* GSM_MAGIC = (*c >> 4) & 0xF; */
|
||||
|
||||
if (((*c >> 4) & 0x0F) != GSM_MAGIC) return -1;
|
||||
|
||||
LARc[0] = (*c++ & 0xF) << 2; /* 1 */
|
||||
LARc[0] |= (*c >> 6) & 0x3;
|
||||
LARc[1] = *c++ & 0x3F;
|
||||
LARc[2] = (*c >> 3) & 0x1F;
|
||||
LARc[3] = (*c++ & 0x7) << 2;
|
||||
LARc[3] |= (*c >> 6) & 0x3;
|
||||
LARc[4] = (*c >> 2) & 0xF;
|
||||
LARc[5] = (*c++ & 0x3) << 2;
|
||||
LARc[5] |= (*c >> 6) & 0x3;
|
||||
LARc[6] = (*c >> 3) & 0x7;
|
||||
LARc[7] = *c++ & 0x7;
|
||||
Nc[0] = (*c >> 1) & 0x7F;
|
||||
bc[0] = (*c++ & 0x1) << 1;
|
||||
bc[0] |= (*c >> 7) & 0x1;
|
||||
Mc[0] = (*c >> 5) & 0x3;
|
||||
xmaxc[0] = (*c++ & 0x1F) << 1;
|
||||
xmaxc[0] |= (*c >> 7) & 0x1;
|
||||
xmc[0] = (*c >> 4) & 0x7;
|
||||
xmc[1] = (*c >> 1) & 0x7;
|
||||
xmc[2] = (*c++ & 0x1) << 2;
|
||||
xmc[2] |= (*c >> 6) & 0x3;
|
||||
xmc[3] = (*c >> 3) & 0x7;
|
||||
xmc[4] = *c++ & 0x7;
|
||||
xmc[5] = (*c >> 5) & 0x7;
|
||||
xmc[6] = (*c >> 2) & 0x7;
|
||||
xmc[7] = (*c++ & 0x3) << 1; /* 10 */
|
||||
xmc[7] |= (*c >> 7) & 0x1;
|
||||
xmc[8] = (*c >> 4) & 0x7;
|
||||
xmc[9] = (*c >> 1) & 0x7;
|
||||
xmc[10] = (*c++ & 0x1) << 2;
|
||||
xmc[10] |= (*c >> 6) & 0x3;
|
||||
xmc[11] = (*c >> 3) & 0x7;
|
||||
xmc[12] = *c++ & 0x7;
|
||||
Nc[1] = (*c >> 1) & 0x7F;
|
||||
bc[1] = (*c++ & 0x1) << 1;
|
||||
bc[1] |= (*c >> 7) & 0x1;
|
||||
Mc[1] = (*c >> 5) & 0x3;
|
||||
xmaxc[1] = (*c++ & 0x1F) << 1;
|
||||
xmaxc[1] |= (*c >> 7) & 0x1;
|
||||
xmc[13] = (*c >> 4) & 0x7;
|
||||
xmc[14] = (*c >> 1) & 0x7;
|
||||
xmc[15] = (*c++ & 0x1) << 2;
|
||||
xmc[15] |= (*c >> 6) & 0x3;
|
||||
xmc[16] = (*c >> 3) & 0x7;
|
||||
xmc[17] = *c++ & 0x7;
|
||||
xmc[18] = (*c >> 5) & 0x7;
|
||||
xmc[19] = (*c >> 2) & 0x7;
|
||||
xmc[20] = (*c++ & 0x3) << 1;
|
||||
xmc[20] |= (*c >> 7) & 0x1;
|
||||
xmc[21] = (*c >> 4) & 0x7;
|
||||
xmc[22] = (*c >> 1) & 0x7;
|
||||
xmc[23] = (*c++ & 0x1) << 2;
|
||||
xmc[23] |= (*c >> 6) & 0x3;
|
||||
xmc[24] = (*c >> 3) & 0x7;
|
||||
xmc[25] = *c++ & 0x7;
|
||||
Nc[2] = (*c >> 1) & 0x7F;
|
||||
bc[2] = (*c++ & 0x1) << 1; /* 20 */
|
||||
bc[2] |= (*c >> 7) & 0x1;
|
||||
Mc[2] = (*c >> 5) & 0x3;
|
||||
xmaxc[2] = (*c++ & 0x1F) << 1;
|
||||
xmaxc[2] |= (*c >> 7) & 0x1;
|
||||
xmc[26] = (*c >> 4) & 0x7;
|
||||
xmc[27] = (*c >> 1) & 0x7;
|
||||
xmc[28] = (*c++ & 0x1) << 2;
|
||||
xmc[28] |= (*c >> 6) & 0x3;
|
||||
xmc[29] = (*c >> 3) & 0x7;
|
||||
xmc[30] = *c++ & 0x7;
|
||||
xmc[31] = (*c >> 5) & 0x7;
|
||||
xmc[32] = (*c >> 2) & 0x7;
|
||||
xmc[33] = (*c++ & 0x3) << 1;
|
||||
xmc[33] |= (*c >> 7) & 0x1;
|
||||
xmc[34] = (*c >> 4) & 0x7;
|
||||
xmc[35] = (*c >> 1) & 0x7;
|
||||
xmc[36] = (*c++ & 0x1) << 2;
|
||||
xmc[36] |= (*c >> 6) & 0x3;
|
||||
xmc[37] = (*c >> 3) & 0x7;
|
||||
xmc[38] = *c++ & 0x7;
|
||||
Nc[3] = (*c >> 1) & 0x7F;
|
||||
bc[3] = (*c++ & 0x1) << 1;
|
||||
bc[3] |= (*c >> 7) & 0x1;
|
||||
Mc[3] = (*c >> 5) & 0x3;
|
||||
xmaxc[3] = (*c++ & 0x1F) << 1;
|
||||
xmaxc[3] |= (*c >> 7) & 0x1;
|
||||
xmc[39] = (*c >> 4) & 0x7;
|
||||
xmc[40] = (*c >> 1) & 0x7;
|
||||
xmc[41] = (*c++ & 0x1) << 2;
|
||||
xmc[41] |= (*c >> 6) & 0x3;
|
||||
xmc[42] = (*c >> 3) & 0x7;
|
||||
xmc[43] = *c++ & 0x7; /* 30 */
|
||||
xmc[44] = (*c >> 5) & 0x7;
|
||||
xmc[45] = (*c >> 2) & 0x7;
|
||||
xmc[46] = (*c++ & 0x3) << 1;
|
||||
xmc[46] |= (*c >> 7) & 0x1;
|
||||
xmc[47] = (*c >> 4) & 0x7;
|
||||
xmc[48] = (*c >> 1) & 0x7;
|
||||
xmc[49] = (*c++ & 0x1) << 2;
|
||||
xmc[49] |= (*c >> 6) & 0x3;
|
||||
xmc[50] = (*c >> 3) & 0x7;
|
||||
xmc[51] = *c & 0x7; /* 33 */
|
||||
}
|
||||
|
||||
Gsm_Decoder(s, LARc, Nc, bc, Mc, xmaxc, xmc, target);
|
||||
|
||||
return 0;
|
||||
}
|
26
utils/iaxclient/lib/gsm/src/gsm_destroy.c
Normal file
26
utils/iaxclient/lib/gsm/src/gsm_destroy.c
Normal file
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
|
||||
* Universitaet Berlin. See the accompanying file "COPYRIGHT" for
|
||||
* details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Header$ */
|
||||
|
||||
#include "gsm.h"
|
||||
#include "config.h"
|
||||
#include "proto.h"
|
||||
|
||||
#ifdef HAS_STDLIB_H
|
||||
# include <stdlib.h>
|
||||
#else
|
||||
# ifdef HAS_MALLOC_H
|
||||
# include <malloc.h>
|
||||
# else
|
||||
extern void free();
|
||||
# endif
|
||||
#endif
|
||||
|
||||
void gsm_destroy P1((S), gsm S)
|
||||
{
|
||||
if (S) free((char *)S);
|
||||
}
|
451
utils/iaxclient/lib/gsm/src/gsm_encode.c
Normal file
451
utils/iaxclient/lib/gsm/src/gsm_encode.c
Normal file
|
@ -0,0 +1,451 @@
|
|||
/*
|
||||
* Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
|
||||
* Universitaet Berlin. See the accompanying file "COPYRIGHT" for
|
||||
* details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Header$ */
|
||||
|
||||
#include "private.h"
|
||||
#include "gsm.h"
|
||||
#include "proto.h"
|
||||
|
||||
void gsm_encode P3((s, source, c), gsm s, gsm_signal * source, gsm_byte * c)
|
||||
{
|
||||
word LARc[8], Nc[4], Mc[4], bc[4], xmaxc[4], xmc[13*4];
|
||||
|
||||
Gsm_Coder(s, source, LARc, Nc, bc, Mc, xmaxc, xmc);
|
||||
|
||||
|
||||
/* variable size
|
||||
|
||||
GSM_MAGIC 4
|
||||
|
||||
LARc[0] 6
|
||||
LARc[1] 6
|
||||
LARc[2] 5
|
||||
LARc[3] 5
|
||||
LARc[4] 4
|
||||
LARc[5] 4
|
||||
LARc[6] 3
|
||||
LARc[7] 3
|
||||
|
||||
Nc[0] 7
|
||||
bc[0] 2
|
||||
Mc[0] 2
|
||||
xmaxc[0] 6
|
||||
xmc[0] 3
|
||||
xmc[1] 3
|
||||
xmc[2] 3
|
||||
xmc[3] 3
|
||||
xmc[4] 3
|
||||
xmc[5] 3
|
||||
xmc[6] 3
|
||||
xmc[7] 3
|
||||
xmc[8] 3
|
||||
xmc[9] 3
|
||||
xmc[10] 3
|
||||
xmc[11] 3
|
||||
xmc[12] 3
|
||||
|
||||
Nc[1] 7
|
||||
bc[1] 2
|
||||
Mc[1] 2
|
||||
xmaxc[1] 6
|
||||
xmc[13] 3
|
||||
xmc[14] 3
|
||||
xmc[15] 3
|
||||
xmc[16] 3
|
||||
xmc[17] 3
|
||||
xmc[18] 3
|
||||
xmc[19] 3
|
||||
xmc[20] 3
|
||||
xmc[21] 3
|
||||
xmc[22] 3
|
||||
xmc[23] 3
|
||||
xmc[24] 3
|
||||
xmc[25] 3
|
||||
|
||||
Nc[2] 7
|
||||
bc[2] 2
|
||||
Mc[2] 2
|
||||
xmaxc[2] 6
|
||||
xmc[26] 3
|
||||
xmc[27] 3
|
||||
xmc[28] 3
|
||||
xmc[29] 3
|
||||
xmc[30] 3
|
||||
xmc[31] 3
|
||||
xmc[32] 3
|
||||
xmc[33] 3
|
||||
xmc[34] 3
|
||||
xmc[35] 3
|
||||
xmc[36] 3
|
||||
xmc[37] 3
|
||||
xmc[38] 3
|
||||
|
||||
Nc[3] 7
|
||||
bc[3] 2
|
||||
Mc[3] 2
|
||||
xmaxc[3] 6
|
||||
xmc[39] 3
|
||||
xmc[40] 3
|
||||
xmc[41] 3
|
||||
xmc[42] 3
|
||||
xmc[43] 3
|
||||
xmc[44] 3
|
||||
xmc[45] 3
|
||||
xmc[46] 3
|
||||
xmc[47] 3
|
||||
xmc[48] 3
|
||||
xmc[49] 3
|
||||
xmc[50] 3
|
||||
xmc[51] 3
|
||||
*/
|
||||
|
||||
#ifdef WAV49
|
||||
|
||||
if (s->wav_fmt) {
|
||||
s->frame_index = !s->frame_index;
|
||||
if (s->frame_index) {
|
||||
|
||||
uword sr;
|
||||
|
||||
sr = 0;
|
||||
sr = sr >> 6 | LARc[0] << 10;
|
||||
sr = sr >> 6 | LARc[1] << 10;
|
||||
*c++ = sr >> 4;
|
||||
sr = sr >> 5 | LARc[2] << 11;
|
||||
*c++ = sr >> 7;
|
||||
sr = sr >> 5 | LARc[3] << 11;
|
||||
sr = sr >> 4 | LARc[4] << 12;
|
||||
*c++ = sr >> 6;
|
||||
sr = sr >> 4 | LARc[5] << 12;
|
||||
sr = sr >> 3 | LARc[6] << 13;
|
||||
*c++ = sr >> 7;
|
||||
sr = sr >> 3 | LARc[7] << 13;
|
||||
sr = sr >> 7 | Nc[0] << 9;
|
||||
*c++ = sr >> 5;
|
||||
sr = sr >> 2 | bc[0] << 14;
|
||||
sr = sr >> 2 | Mc[0] << 14;
|
||||
sr = sr >> 6 | xmaxc[0] << 10;
|
||||
*c++ = sr >> 3;
|
||||
sr = sr >> 3 | xmc[0] << 13;
|
||||
*c++ = sr >> 8;
|
||||
sr = sr >> 3 | xmc[1] << 13;
|
||||
sr = sr >> 3 | xmc[2] << 13;
|
||||
sr = sr >> 3 | xmc[3] << 13;
|
||||
*c++ = sr >> 7;
|
||||
sr = sr >> 3 | xmc[4] << 13;
|
||||
sr = sr >> 3 | xmc[5] << 13;
|
||||
sr = sr >> 3 | xmc[6] << 13;
|
||||
*c++ = sr >> 6;
|
||||
sr = sr >> 3 | xmc[7] << 13;
|
||||
sr = sr >> 3 | xmc[8] << 13;
|
||||
*c++ = sr >> 8;
|
||||
sr = sr >> 3 | xmc[9] << 13;
|
||||
sr = sr >> 3 | xmc[10] << 13;
|
||||
sr = sr >> 3 | xmc[11] << 13;
|
||||
*c++ = sr >> 7;
|
||||
sr = sr >> 3 | xmc[12] << 13;
|
||||
sr = sr >> 7 | Nc[1] << 9;
|
||||
*c++ = sr >> 5;
|
||||
sr = sr >> 2 | bc[1] << 14;
|
||||
sr = sr >> 2 | Mc[1] << 14;
|
||||
sr = sr >> 6 | xmaxc[1] << 10;
|
||||
*c++ = sr >> 3;
|
||||
sr = sr >> 3 | xmc[13] << 13;
|
||||
*c++ = sr >> 8;
|
||||
sr = sr >> 3 | xmc[14] << 13;
|
||||
sr = sr >> 3 | xmc[15] << 13;
|
||||
sr = sr >> 3 | xmc[16] << 13;
|
||||
*c++ = sr >> 7;
|
||||
sr = sr >> 3 | xmc[17] << 13;
|
||||
sr = sr >> 3 | xmc[18] << 13;
|
||||
sr = sr >> 3 | xmc[19] << 13;
|
||||
*c++ = sr >> 6;
|
||||
sr = sr >> 3 | xmc[20] << 13;
|
||||
sr = sr >> 3 | xmc[21] << 13;
|
||||
*c++ = sr >> 8;
|
||||
sr = sr >> 3 | xmc[22] << 13;
|
||||
sr = sr >> 3 | xmc[23] << 13;
|
||||
sr = sr >> 3 | xmc[24] << 13;
|
||||
*c++ = sr >> 7;
|
||||
sr = sr >> 3 | xmc[25] << 13;
|
||||
sr = sr >> 7 | Nc[2] << 9;
|
||||
*c++ = sr >> 5;
|
||||
sr = sr >> 2 | bc[2] << 14;
|
||||
sr = sr >> 2 | Mc[2] << 14;
|
||||
sr = sr >> 6 | xmaxc[2] << 10;
|
||||
*c++ = sr >> 3;
|
||||
sr = sr >> 3 | xmc[26] << 13;
|
||||
*c++ = sr >> 8;
|
||||
sr = sr >> 3 | xmc[27] << 13;
|
||||
sr = sr >> 3 | xmc[28] << 13;
|
||||
sr = sr >> 3 | xmc[29] << 13;
|
||||
*c++ = sr >> 7;
|
||||
sr = sr >> 3 | xmc[30] << 13;
|
||||
sr = sr >> 3 | xmc[31] << 13;
|
||||
sr = sr >> 3 | xmc[32] << 13;
|
||||
*c++ = sr >> 6;
|
||||
sr = sr >> 3 | xmc[33] << 13;
|
||||
sr = sr >> 3 | xmc[34] << 13;
|
||||
*c++ = sr >> 8;
|
||||
sr = sr >> 3 | xmc[35] << 13;
|
||||
sr = sr >> 3 | xmc[36] << 13;
|
||||
sr = sr >> 3 | xmc[37] << 13;
|
||||
*c++ = sr >> 7;
|
||||
sr = sr >> 3 | xmc[38] << 13;
|
||||
sr = sr >> 7 | Nc[3] << 9;
|
||||
*c++ = sr >> 5;
|
||||
sr = sr >> 2 | bc[3] << 14;
|
||||
sr = sr >> 2 | Mc[3] << 14;
|
||||
sr = sr >> 6 | xmaxc[3] << 10;
|
||||
*c++ = sr >> 3;
|
||||
sr = sr >> 3 | xmc[39] << 13;
|
||||
*c++ = sr >> 8;
|
||||
sr = sr >> 3 | xmc[40] << 13;
|
||||
sr = sr >> 3 | xmc[41] << 13;
|
||||
sr = sr >> 3 | xmc[42] << 13;
|
||||
*c++ = sr >> 7;
|
||||
sr = sr >> 3 | xmc[43] << 13;
|
||||
sr = sr >> 3 | xmc[44] << 13;
|
||||
sr = sr >> 3 | xmc[45] << 13;
|
||||
*c++ = sr >> 6;
|
||||
sr = sr >> 3 | xmc[46] << 13;
|
||||
sr = sr >> 3 | xmc[47] << 13;
|
||||
*c++ = sr >> 8;
|
||||
sr = sr >> 3 | xmc[48] << 13;
|
||||
sr = sr >> 3 | xmc[49] << 13;
|
||||
sr = sr >> 3 | xmc[50] << 13;
|
||||
*c++ = sr >> 7;
|
||||
sr = sr >> 3 | xmc[51] << 13;
|
||||
sr = sr >> 4;
|
||||
*c = sr >> 8;
|
||||
s->frame_chain = *c;
|
||||
}
|
||||
else {
|
||||
uword sr;
|
||||
|
||||
sr = 0;
|
||||
sr = sr >> 4 | s->frame_chain << 12;
|
||||
sr = sr >> 6 | LARc[0] << 10;
|
||||
*c++ = sr >> 6;
|
||||
sr = sr >> 6 | LARc[1] << 10;
|
||||
*c++ = sr >> 8;
|
||||
sr = sr >> 5 | LARc[2] << 11;
|
||||
sr = sr >> 5 | LARc[3] << 11;
|
||||
*c++ = sr >> 6;
|
||||
sr = sr >> 4 | LARc[4] << 12;
|
||||
sr = sr >> 4 | LARc[5] << 12;
|
||||
*c++ = sr >> 6;
|
||||
sr = sr >> 3 | LARc[6] << 13;
|
||||
sr = sr >> 3 | LARc[7] << 13;
|
||||
*c++ = sr >> 8;
|
||||
sr = sr >> 7 | Nc[0] << 9;
|
||||
sr = sr >> 2 | bc[0] << 14;
|
||||
*c++ = sr >> 7;
|
||||
sr = sr >> 2 | Mc[0] << 14;
|
||||
sr = sr >> 6 | xmaxc[0] << 10;
|
||||
*c++ = sr >> 7;
|
||||
sr = sr >> 3 | xmc[0] << 13;
|
||||
sr = sr >> 3 | xmc[1] << 13;
|
||||
sr = sr >> 3 | xmc[2] << 13;
|
||||
*c++ = sr >> 6;
|
||||
sr = sr >> 3 | xmc[3] << 13;
|
||||
sr = sr >> 3 | xmc[4] << 13;
|
||||
*c++ = sr >> 8;
|
||||
sr = sr >> 3 | xmc[5] << 13;
|
||||
sr = sr >> 3 | xmc[6] << 13;
|
||||
sr = sr >> 3 | xmc[7] << 13;
|
||||
*c++ = sr >> 7;
|
||||
sr = sr >> 3 | xmc[8] << 13;
|
||||
sr = sr >> 3 | xmc[9] << 13;
|
||||
sr = sr >> 3 | xmc[10] << 13;
|
||||
*c++ = sr >> 6;
|
||||
sr = sr >> 3 | xmc[11] << 13;
|
||||
sr = sr >> 3 | xmc[12] << 13;
|
||||
*c++ = sr >> 8;
|
||||
sr = sr >> 7 | Nc[1] << 9;
|
||||
sr = sr >> 2 | bc[1] << 14;
|
||||
*c++ = sr >> 7;
|
||||
sr = sr >> 2 | Mc[1] << 14;
|
||||
sr = sr >> 6 | xmaxc[1] << 10;
|
||||
*c++ = sr >> 7;
|
||||
sr = sr >> 3 | xmc[13] << 13;
|
||||
sr = sr >> 3 | xmc[14] << 13;
|
||||
sr = sr >> 3 | xmc[15] << 13;
|
||||
*c++ = sr >> 6;
|
||||
sr = sr >> 3 | xmc[16] << 13;
|
||||
sr = sr >> 3 | xmc[17] << 13;
|
||||
*c++ = sr >> 8;
|
||||
sr = sr >> 3 | xmc[18] << 13;
|
||||
sr = sr >> 3 | xmc[19] << 13;
|
||||
sr = sr >> 3 | xmc[20] << 13;
|
||||
*c++ = sr >> 7;
|
||||
sr = sr >> 3 | xmc[21] << 13;
|
||||
sr = sr >> 3 | xmc[22] << 13;
|
||||
sr = sr >> 3 | xmc[23] << 13;
|
||||
*c++ = sr >> 6;
|
||||
sr = sr >> 3 | xmc[24] << 13;
|
||||
sr = sr >> 3 | xmc[25] << 13;
|
||||
*c++ = sr >> 8;
|
||||
sr = sr >> 7 | Nc[2] << 9;
|
||||
sr = sr >> 2 | bc[2] << 14;
|
||||
*c++ = sr >> 7;
|
||||
sr = sr >> 2 | Mc[2] << 14;
|
||||
sr = sr >> 6 | xmaxc[2] << 10;
|
||||
*c++ = sr >> 7;
|
||||
sr = sr >> 3 | xmc[26] << 13;
|
||||
sr = sr >> 3 | xmc[27] << 13;
|
||||
sr = sr >> 3 | xmc[28] << 13;
|
||||
*c++ = sr >> 6;
|
||||
sr = sr >> 3 | xmc[29] << 13;
|
||||
sr = sr >> 3 | xmc[30] << 13;
|
||||
*c++ = sr >> 8;
|
||||
sr = sr >> 3 | xmc[31] << 13;
|
||||
sr = sr >> 3 | xmc[32] << 13;
|
||||
sr = sr >> 3 | xmc[33] << 13;
|
||||
*c++ = sr >> 7;
|
||||
sr = sr >> 3 | xmc[34] << 13;
|
||||
sr = sr >> 3 | xmc[35] << 13;
|
||||
sr = sr >> 3 | xmc[36] << 13;
|
||||
*c++ = sr >> 6;
|
||||
sr = sr >> 3 | xmc[37] << 13;
|
||||
sr = sr >> 3 | xmc[38] << 13;
|
||||
*c++ = sr >> 8;
|
||||
sr = sr >> 7 | Nc[3] << 9;
|
||||
sr = sr >> 2 | bc[3] << 14;
|
||||
*c++ = sr >> 7;
|
||||
sr = sr >> 2 | Mc[3] << 14;
|
||||
sr = sr >> 6 | xmaxc[3] << 10;
|
||||
*c++ = sr >> 7;
|
||||
sr = sr >> 3 | xmc[39] << 13;
|
||||
sr = sr >> 3 | xmc[40] << 13;
|
||||
sr = sr >> 3 | xmc[41] << 13;
|
||||
*c++ = sr >> 6;
|
||||
sr = sr >> 3 | xmc[42] << 13;
|
||||
sr = sr >> 3 | xmc[43] << 13;
|
||||
*c++ = sr >> 8;
|
||||
sr = sr >> 3 | xmc[44] << 13;
|
||||
sr = sr >> 3 | xmc[45] << 13;
|
||||
sr = sr >> 3 | xmc[46] << 13;
|
||||
*c++ = sr >> 7;
|
||||
sr = sr >> 3 | xmc[47] << 13;
|
||||
sr = sr >> 3 | xmc[48] << 13;
|
||||
sr = sr >> 3 | xmc[49] << 13;
|
||||
*c++ = sr >> 6;
|
||||
sr = sr >> 3 | xmc[50] << 13;
|
||||
sr = sr >> 3 | xmc[51] << 13;
|
||||
*c++ = sr >> 8;
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
|
||||
#endif /* WAV49 */
|
||||
{
|
||||
|
||||
*c++ = ((GSM_MAGIC & 0xF) << 4) /* 1 */
|
||||
| ((LARc[0] >> 2) & 0xF);
|
||||
*c++ = ((LARc[0] & 0x3) << 6)
|
||||
| (LARc[1] & 0x3F);
|
||||
*c++ = ((LARc[2] & 0x1F) << 3)
|
||||
| ((LARc[3] >> 2) & 0x7);
|
||||
*c++ = ((LARc[3] & 0x3) << 6)
|
||||
| ((LARc[4] & 0xF) << 2)
|
||||
| ((LARc[5] >> 2) & 0x3);
|
||||
*c++ = ((LARc[5] & 0x3) << 6)
|
||||
| ((LARc[6] & 0x7) << 3)
|
||||
| (LARc[7] & 0x7);
|
||||
*c++ = ((Nc[0] & 0x7F) << 1)
|
||||
| ((bc[0] >> 1) & 0x1);
|
||||
*c++ = ((bc[0] & 0x1) << 7)
|
||||
| ((Mc[0] & 0x3) << 5)
|
||||
| ((xmaxc[0] >> 1) & 0x1F);
|
||||
*c++ = ((xmaxc[0] & 0x1) << 7)
|
||||
| ((xmc[0] & 0x7) << 4)
|
||||
| ((xmc[1] & 0x7) << 1)
|
||||
| ((xmc[2] >> 2) & 0x1);
|
||||
*c++ = ((xmc[2] & 0x3) << 6)
|
||||
| ((xmc[3] & 0x7) << 3)
|
||||
| (xmc[4] & 0x7);
|
||||
*c++ = ((xmc[5] & 0x7) << 5) /* 10 */
|
||||
| ((xmc[6] & 0x7) << 2)
|
||||
| ((xmc[7] >> 1) & 0x3);
|
||||
*c++ = ((xmc[7] & 0x1) << 7)
|
||||
| ((xmc[8] & 0x7) << 4)
|
||||
| ((xmc[9] & 0x7) << 1)
|
||||
| ((xmc[10] >> 2) & 0x1);
|
||||
*c++ = ((xmc[10] & 0x3) << 6)
|
||||
| ((xmc[11] & 0x7) << 3)
|
||||
| (xmc[12] & 0x7);
|
||||
*c++ = ((Nc[1] & 0x7F) << 1)
|
||||
| ((bc[1] >> 1) & 0x1);
|
||||
*c++ = ((bc[1] & 0x1) << 7)
|
||||
| ((Mc[1] & 0x3) << 5)
|
||||
| ((xmaxc[1] >> 1) & 0x1F);
|
||||
*c++ = ((xmaxc[1] & 0x1) << 7)
|
||||
| ((xmc[13] & 0x7) << 4)
|
||||
| ((xmc[14] & 0x7) << 1)
|
||||
| ((xmc[15] >> 2) & 0x1);
|
||||
*c++ = ((xmc[15] & 0x3) << 6)
|
||||
| ((xmc[16] & 0x7) << 3)
|
||||
| (xmc[17] & 0x7);
|
||||
*c++ = ((xmc[18] & 0x7) << 5)
|
||||
| ((xmc[19] & 0x7) << 2)
|
||||
| ((xmc[20] >> 1) & 0x3);
|
||||
*c++ = ((xmc[20] & 0x1) << 7)
|
||||
| ((xmc[21] & 0x7) << 4)
|
||||
| ((xmc[22] & 0x7) << 1)
|
||||
| ((xmc[23] >> 2) & 0x1);
|
||||
*c++ = ((xmc[23] & 0x3) << 6)
|
||||
| ((xmc[24] & 0x7) << 3)
|
||||
| (xmc[25] & 0x7);
|
||||
*c++ = ((Nc[2] & 0x7F) << 1) /* 20 */
|
||||
| ((bc[2] >> 1) & 0x1);
|
||||
*c++ = ((bc[2] & 0x1) << 7)
|
||||
| ((Mc[2] & 0x3) << 5)
|
||||
| ((xmaxc[2] >> 1) & 0x1F);
|
||||
*c++ = ((xmaxc[2] & 0x1) << 7)
|
||||
| ((xmc[26] & 0x7) << 4)
|
||||
| ((xmc[27] & 0x7) << 1)
|
||||
| ((xmc[28] >> 2) & 0x1);
|
||||
*c++ = ((xmc[28] & 0x3) << 6)
|
||||
| ((xmc[29] & 0x7) << 3)
|
||||
| (xmc[30] & 0x7);
|
||||
*c++ = ((xmc[31] & 0x7) << 5)
|
||||
| ((xmc[32] & 0x7) << 2)
|
||||
| ((xmc[33] >> 1) & 0x3);
|
||||
*c++ = ((xmc[33] & 0x1) << 7)
|
||||
| ((xmc[34] & 0x7) << 4)
|
||||
| ((xmc[35] & 0x7) << 1)
|
||||
| ((xmc[36] >> 2) & 0x1);
|
||||
*c++ = ((xmc[36] & 0x3) << 6)
|
||||
| ((xmc[37] & 0x7) << 3)
|
||||
| (xmc[38] & 0x7);
|
||||
*c++ = ((Nc[3] & 0x7F) << 1)
|
||||
| ((bc[3] >> 1) & 0x1);
|
||||
*c++ = ((bc[3] & 0x1) << 7)
|
||||
| ((Mc[3] & 0x3) << 5)
|
||||
| ((xmaxc[3] >> 1) & 0x1F);
|
||||
*c++ = ((xmaxc[3] & 0x1) << 7)
|
||||
| ((xmc[39] & 0x7) << 4)
|
||||
| ((xmc[40] & 0x7) << 1)
|
||||
| ((xmc[41] >> 2) & 0x1);
|
||||
*c++ = ((xmc[41] & 0x3) << 6) /* 30 */
|
||||
| ((xmc[42] & 0x7) << 3)
|
||||
| (xmc[43] & 0x7);
|
||||
*c++ = ((xmc[44] & 0x7) << 5)
|
||||
| ((xmc[45] & 0x7) << 2)
|
||||
| ((xmc[46] >> 1) & 0x3);
|
||||
*c++ = ((xmc[46] & 0x1) << 7)
|
||||
| ((xmc[47] & 0x7) << 4)
|
||||
| ((xmc[48] & 0x7) << 1)
|
||||
| ((xmc[49] >> 2) & 0x1);
|
||||
*c++ = ((xmc[49] & 0x3) << 6)
|
||||
| ((xmc[50] & 0x7) << 3)
|
||||
| (xmc[51] & 0x7);
|
||||
|
||||
}
|
||||
}
|
417
utils/iaxclient/lib/gsm/src/gsm_explode.c
Normal file
417
utils/iaxclient/lib/gsm/src/gsm_explode.c
Normal file
|
@ -0,0 +1,417 @@
|
|||
/*
|
||||
* Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
|
||||
* Universitaet Berlin. See the accompanying file "COPYRIGHT" for
|
||||
* details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Header$ */
|
||||
|
||||
#include "private.h"
|
||||
#include "gsm.h"
|
||||
#include "proto.h"
|
||||
|
||||
int gsm_explode P3((s, c, target), gsm s, gsm_byte * c, gsm_signal * target)
|
||||
{
|
||||
# define LARc target
|
||||
# define Nc *((gsm_signal (*) [17])(target + 8))
|
||||
# define bc *((gsm_signal (*) [17])(target + 9))
|
||||
# define Mc *((gsm_signal (*) [17])(target + 10))
|
||||
# define xmaxc *((gsm_signal (*) [17])(target + 11))
|
||||
|
||||
|
||||
#ifdef WAV49
|
||||
if (s->wav_fmt) {
|
||||
|
||||
uword sr = 0;
|
||||
|
||||
if (s->frame_index == 1) {
|
||||
|
||||
sr = *c++;
|
||||
LARc[0] = sr & 0x3f; sr >>= 6;
|
||||
sr |= (uword)*c++ << 2;
|
||||
LARc[1] = sr & 0x3f; sr >>= 6;
|
||||
sr |= (uword)*c++ << 4;
|
||||
LARc[2] = sr & 0x1f; sr >>= 5;
|
||||
LARc[3] = sr & 0x1f; sr >>= 5;
|
||||
sr |= (uword)*c++ << 2;
|
||||
LARc[4] = sr & 0xf; sr >>= 4;
|
||||
LARc[5] = sr & 0xf; sr >>= 4;
|
||||
sr |= (uword)*c++ << 2; /* 5 */
|
||||
LARc[6] = sr & 0x7; sr >>= 3;
|
||||
LARc[7] = sr & 0x7; sr >>= 3;
|
||||
sr |= (uword)*c++ << 4;
|
||||
Nc[0] = sr & 0x7f; sr >>= 7;
|
||||
bc[0] = sr & 0x3; sr >>= 2;
|
||||
Mc[0] = sr & 0x3; sr >>= 2;
|
||||
sr |= (uword)*c++ << 1;
|
||||
xmaxc[0] = sr & 0x3f; sr >>= 6;
|
||||
#undef xmc
|
||||
#define xmc (target + 12)
|
||||
xmc[0] = sr & 0x7; sr >>= 3;
|
||||
sr = *c++;
|
||||
xmc[1] = sr & 0x7; sr >>= 3;
|
||||
xmc[2] = sr & 0x7; sr >>= 3;
|
||||
sr |= (uword)*c++ << 2;
|
||||
xmc[3] = sr & 0x7; sr >>= 3;
|
||||
xmc[4] = sr & 0x7; sr >>= 3;
|
||||
xmc[5] = sr & 0x7; sr >>= 3;
|
||||
sr |= (uword)*c++ << 1; /* 10 */
|
||||
xmc[6] = sr & 0x7; sr >>= 3;
|
||||
xmc[7] = sr & 0x7; sr >>= 3;
|
||||
xmc[8] = sr & 0x7; sr >>= 3;
|
||||
sr = *c++;
|
||||
xmc[9] = sr & 0x7; sr >>= 3;
|
||||
xmc[10] = sr & 0x7; sr >>= 3;
|
||||
sr |= (uword)*c++ << 2;
|
||||
xmc[11] = sr & 0x7; sr >>= 3;
|
||||
xmc[12] = sr & 0x7; sr >>= 3;
|
||||
sr |= (uword)*c++ << 4;
|
||||
Nc[1] = sr & 0x7f; sr >>= 7;
|
||||
bc[1] = sr & 0x3; sr >>= 2;
|
||||
Mc[1] = sr & 0x3; sr >>= 2;
|
||||
sr |= (uword)*c++ << 1;
|
||||
xmaxc[1] = sr & 0x3f; sr >>= 6;
|
||||
#undef xmc
|
||||
#define xmc (target + 29 - 13)
|
||||
|
||||
xmc[13] = sr & 0x7; sr >>= 3;
|
||||
sr = *c++; /* 15 */
|
||||
xmc[14] = sr & 0x7; sr >>= 3;
|
||||
xmc[15] = sr & 0x7; sr >>= 3;
|
||||
sr |= (uword)*c++ << 2;
|
||||
xmc[16] = sr & 0x7; sr >>= 3;
|
||||
xmc[17] = sr & 0x7; sr >>= 3;
|
||||
xmc[18] = sr & 0x7; sr >>= 3;
|
||||
sr |= (uword)*c++ << 1;
|
||||
xmc[19] = sr & 0x7; sr >>= 3;
|
||||
xmc[20] = sr & 0x7; sr >>= 3;
|
||||
xmc[21] = sr & 0x7; sr >>= 3;
|
||||
sr = *c++;
|
||||
xmc[22] = sr & 0x7; sr >>= 3;
|
||||
xmc[23] = sr & 0x7; sr >>= 3;
|
||||
sr |= (uword)*c++ << 2;
|
||||
xmc[24] = sr & 0x7; sr >>= 3;
|
||||
xmc[25] = sr & 0x7; sr >>= 3;
|
||||
sr |= (uword)*c++ << 4; /* 20 */
|
||||
Nc[2] = sr & 0x7f; sr >>= 7;
|
||||
bc[2] = sr & 0x3; sr >>= 2;
|
||||
Mc[2] = sr & 0x3; sr >>= 2;
|
||||
sr |= (uword)*c++ << 1;
|
||||
xmaxc[2] = sr & 0x3f; sr >>= 6;
|
||||
|
||||
#undef xmc
|
||||
#define xmc (target + 46 - 26)
|
||||
|
||||
xmc[26] = sr & 0x7; sr >>= 3;
|
||||
sr = *c++;
|
||||
xmc[27] = sr & 0x7; sr >>= 3;
|
||||
xmc[28] = sr & 0x7; sr >>= 3;
|
||||
sr |= (uword)*c++ << 2;
|
||||
xmc[29] = sr & 0x7; sr >>= 3;
|
||||
xmc[30] = sr & 0x7; sr >>= 3;
|
||||
xmc[31] = sr & 0x7; sr >>= 3;
|
||||
sr |= (uword)*c++ << 1;
|
||||
xmc[32] = sr & 0x7; sr >>= 3;
|
||||
xmc[33] = sr & 0x7; sr >>= 3;
|
||||
xmc[34] = sr & 0x7; sr >>= 3;
|
||||
sr = *c++; /* 25 */
|
||||
xmc[35] = sr & 0x7; sr >>= 3;
|
||||
xmc[36] = sr & 0x7; sr >>= 3;
|
||||
sr |= (uword)*c++ << 2;
|
||||
xmc[37] = sr & 0x7; sr >>= 3;
|
||||
xmc[38] = sr & 0x7; sr >>= 3;
|
||||
sr |= (uword)*c++ << 4;
|
||||
Nc[3] = sr & 0x7f; sr >>= 7;
|
||||
bc[3] = sr & 0x3; sr >>= 2;
|
||||
Mc[3] = sr & 0x3; sr >>= 2;
|
||||
sr |= (uword)*c++ << 1;
|
||||
xmaxc[3] = sr & 0x3f; sr >>= 6;
|
||||
#undef xmc
|
||||
#define xmc (target + 63 - 39)
|
||||
|
||||
xmc[39] = sr & 0x7; sr >>= 3;
|
||||
sr = *c++;
|
||||
xmc[40] = sr & 0x7; sr >>= 3;
|
||||
xmc[41] = sr & 0x7; sr >>= 3;
|
||||
sr |= (uword)*c++ << 2; /* 30 */
|
||||
xmc[42] = sr & 0x7; sr >>= 3;
|
||||
xmc[43] = sr & 0x7; sr >>= 3;
|
||||
xmc[44] = sr & 0x7; sr >>= 3;
|
||||
sr |= (uword)*c++ << 1;
|
||||
xmc[45] = sr & 0x7; sr >>= 3;
|
||||
xmc[46] = sr & 0x7; sr >>= 3;
|
||||
xmc[47] = sr & 0x7; sr >>= 3;
|
||||
sr = *c++;
|
||||
xmc[48] = sr & 0x7; sr >>= 3;
|
||||
xmc[49] = sr & 0x7; sr >>= 3;
|
||||
sr |= (uword)*c++ << 2;
|
||||
xmc[50] = sr & 0x7; sr >>= 3;
|
||||
xmc[51] = sr & 0x7; sr >>= 3;
|
||||
|
||||
s->frame_chain = sr & 0xf;
|
||||
}
|
||||
else {
|
||||
sr = s->frame_chain;
|
||||
sr |= (uword)*c++ << 4; /* 1 */
|
||||
LARc[0] = sr & 0x3f; sr >>= 6;
|
||||
LARc[1] = sr & 0x3f; sr >>= 6;
|
||||
sr = *c++;
|
||||
LARc[2] = sr & 0x1f; sr >>= 5;
|
||||
sr |= (uword)*c++ << 3;
|
||||
LARc[3] = sr & 0x1f; sr >>= 5;
|
||||
LARc[4] = sr & 0xf; sr >>= 4;
|
||||
sr |= (uword)*c++ << 2;
|
||||
LARc[5] = sr & 0xf; sr >>= 4;
|
||||
LARc[6] = sr & 0x7; sr >>= 3;
|
||||
LARc[7] = sr & 0x7; sr >>= 3;
|
||||
sr = *c++; /* 5 */
|
||||
Nc[0] = sr & 0x7f; sr >>= 7;
|
||||
sr |= (uword)*c++ << 1;
|
||||
bc[0] = sr & 0x3; sr >>= 2;
|
||||
Mc[0] = sr & 0x3; sr >>= 2;
|
||||
sr |= (uword)*c++ << 5;
|
||||
xmaxc[0] = sr & 0x3f; sr >>= 6;
|
||||
#undef xmc
|
||||
#define xmc (target + 12)
|
||||
xmc[0] = sr & 0x7; sr >>= 3;
|
||||
xmc[1] = sr & 0x7; sr >>= 3;
|
||||
sr |= (uword)*c++ << 1;
|
||||
xmc[2] = sr & 0x7; sr >>= 3;
|
||||
xmc[3] = sr & 0x7; sr >>= 3;
|
||||
xmc[4] = sr & 0x7; sr >>= 3;
|
||||
sr = *c++;
|
||||
xmc[5] = sr & 0x7; sr >>= 3;
|
||||
xmc[6] = sr & 0x7; sr >>= 3;
|
||||
sr |= (uword)*c++ << 2; /* 10 */
|
||||
xmc[7] = sr & 0x7; sr >>= 3;
|
||||
xmc[8] = sr & 0x7; sr >>= 3;
|
||||
xmc[9] = sr & 0x7; sr >>= 3;
|
||||
sr |= (uword)*c++ << 1;
|
||||
xmc[10] = sr & 0x7; sr >>= 3;
|
||||
xmc[11] = sr & 0x7; sr >>= 3;
|
||||
xmc[12] = sr & 0x7; sr >>= 3;
|
||||
sr = *c++;
|
||||
Nc[1] = sr & 0x7f; sr >>= 7;
|
||||
sr |= (uword)*c++ << 1;
|
||||
bc[1] = sr & 0x3; sr >>= 2;
|
||||
Mc[1] = sr & 0x3; sr >>= 2;
|
||||
sr |= (uword)*c++ << 5;
|
||||
xmaxc[1] = sr & 0x3f; sr >>= 6;
|
||||
#undef xmc
|
||||
#define xmc (target + 29 - 13)
|
||||
|
||||
xmc[13] = sr & 0x7; sr >>= 3;
|
||||
xmc[14] = sr & 0x7; sr >>= 3;
|
||||
sr |= (uword)*c++ << 1; /* 15 */
|
||||
xmc[15] = sr & 0x7; sr >>= 3;
|
||||
xmc[16] = sr & 0x7; sr >>= 3;
|
||||
xmc[17] = sr & 0x7; sr >>= 3;
|
||||
sr = *c++;
|
||||
xmc[18] = sr & 0x7; sr >>= 3;
|
||||
xmc[19] = sr & 0x7; sr >>= 3;
|
||||
sr |= (uword)*c++ << 2;
|
||||
xmc[20] = sr & 0x7; sr >>= 3;
|
||||
xmc[21] = sr & 0x7; sr >>= 3;
|
||||
xmc[22] = sr & 0x7; sr >>= 3;
|
||||
sr |= (uword)*c++ << 1;
|
||||
xmc[23] = sr & 0x7; sr >>= 3;
|
||||
xmc[24] = sr & 0x7; sr >>= 3;
|
||||
xmc[25] = sr & 0x7; sr >>= 3;
|
||||
sr = *c++;
|
||||
Nc[2] = sr & 0x7f; sr >>= 7;
|
||||
sr |= (uword)*c++ << 1; /* 20 */
|
||||
bc[2] = sr & 0x3; sr >>= 2;
|
||||
Mc[2] = sr & 0x3; sr >>= 2;
|
||||
sr |= (uword)*c++ << 5;
|
||||
xmaxc[2] = sr & 0x3f; sr >>= 6;
|
||||
#undef xmc
|
||||
#define xmc (target + 46 - 26)
|
||||
xmc[26] = sr & 0x7; sr >>= 3;
|
||||
xmc[27] = sr & 0x7; sr >>= 3;
|
||||
sr |= (uword)*c++ << 1;
|
||||
xmc[28] = sr & 0x7; sr >>= 3;
|
||||
xmc[29] = sr & 0x7; sr >>= 3;
|
||||
xmc[30] = sr & 0x7; sr >>= 3;
|
||||
sr = *c++;
|
||||
xmc[31] = sr & 0x7; sr >>= 3;
|
||||
xmc[32] = sr & 0x7; sr >>= 3;
|
||||
sr |= (uword)*c++ << 2;
|
||||
xmc[33] = sr & 0x7; sr >>= 3;
|
||||
xmc[34] = sr & 0x7; sr >>= 3;
|
||||
xmc[35] = sr & 0x7; sr >>= 3;
|
||||
sr |= (uword)*c++ << 1; /* 25 */
|
||||
xmc[36] = sr & 0x7; sr >>= 3;
|
||||
xmc[37] = sr & 0x7; sr >>= 3;
|
||||
xmc[38] = sr & 0x7; sr >>= 3;
|
||||
sr = *c++;
|
||||
Nc[3] = sr & 0x7f; sr >>= 7;
|
||||
sr |= (uword)*c++ << 1;
|
||||
bc[3] = sr & 0x3; sr >>= 2;
|
||||
Mc[3] = sr & 0x3; sr >>= 2;
|
||||
sr |= (uword)*c++ << 5;
|
||||
xmaxc[3] = sr & 0x3f; sr >>= 6;
|
||||
|
||||
#undef xmc
|
||||
#define xmc (target + 63 - 39)
|
||||
|
||||
xmc[39] = sr & 0x7; sr >>= 3;
|
||||
xmc[40] = sr & 0x7; sr >>= 3;
|
||||
sr |= (uword)*c++ << 1;
|
||||
xmc[41] = sr & 0x7; sr >>= 3;
|
||||
xmc[42] = sr & 0x7; sr >>= 3;
|
||||
xmc[43] = sr & 0x7; sr >>= 3;
|
||||
sr = *c++; /* 30 */
|
||||
xmc[44] = sr & 0x7; sr >>= 3;
|
||||
xmc[45] = sr & 0x7; sr >>= 3;
|
||||
sr |= (uword)*c++ << 2;
|
||||
xmc[46] = sr & 0x7; sr >>= 3;
|
||||
xmc[47] = sr & 0x7; sr >>= 3;
|
||||
xmc[48] = sr & 0x7; sr >>= 3;
|
||||
sr |= (uword)*c++ << 1;
|
||||
xmc[49] = sr & 0x7; sr >>= 3;
|
||||
xmc[50] = sr & 0x7; sr >>= 3;
|
||||
xmc[51] = sr & 0x7; sr >>= 3;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
/* GSM_MAGIC = (*c >> 4) & 0xF; */
|
||||
|
||||
if (((*c >> 4) & 0x0F) != GSM_MAGIC) return -1;
|
||||
|
||||
LARc[0] = (*c++ & 0xF) << 2; /* 1 */
|
||||
LARc[0] |= (*c >> 6) & 0x3;
|
||||
LARc[1] = *c++ & 0x3F;
|
||||
LARc[2] = (*c >> 3) & 0x1F;
|
||||
LARc[3] = (*c++ & 0x7) << 2;
|
||||
LARc[3] |= (*c >> 6) & 0x3;
|
||||
LARc[4] = (*c >> 2) & 0xF;
|
||||
LARc[5] = (*c++ & 0x3) << 2;
|
||||
LARc[5] |= (*c >> 6) & 0x3;
|
||||
LARc[6] = (*c >> 3) & 0x7;
|
||||
LARc[7] = *c++ & 0x7;
|
||||
|
||||
Nc[0] = (*c >> 1) & 0x7F;
|
||||
|
||||
bc[0] = (*c++ & 0x1) << 1;
|
||||
bc[0] |= (*c >> 7) & 0x1;
|
||||
|
||||
Mc[0] = (*c >> 5) & 0x3;
|
||||
|
||||
xmaxc[0] = (*c++ & 0x1F) << 1;
|
||||
xmaxc[0] |= (*c >> 7) & 0x1;
|
||||
|
||||
#undef xmc
|
||||
#define xmc (target + 12)
|
||||
|
||||
xmc[0] = (*c >> 4) & 0x7;
|
||||
xmc[1] = (*c >> 1) & 0x7;
|
||||
xmc[2] = (*c++ & 0x1) << 2;
|
||||
xmc[2] |= (*c >> 6) & 0x3;
|
||||
xmc[3] = (*c >> 3) & 0x7;
|
||||
xmc[4] = *c++ & 0x7;
|
||||
xmc[5] = (*c >> 5) & 0x7;
|
||||
xmc[6] = (*c >> 2) & 0x7;
|
||||
xmc[7] = (*c++ & 0x3) << 1; /* 10 */
|
||||
xmc[7] |= (*c >> 7) & 0x1;
|
||||
xmc[8] = (*c >> 4) & 0x7;
|
||||
xmc[9] = (*c >> 1) & 0x7;
|
||||
xmc[10] = (*c++ & 0x1) << 2;
|
||||
xmc[10] |= (*c >> 6) & 0x3;
|
||||
xmc[11] = (*c >> 3) & 0x7;
|
||||
xmc[12] = *c++ & 0x7;
|
||||
|
||||
Nc[1] = (*c >> 1) & 0x7F;
|
||||
|
||||
bc[1] = (*c++ & 0x1) << 1;
|
||||
bc[1] |= (*c >> 7) & 0x1;
|
||||
|
||||
Mc[1] = (*c >> 5) & 0x3;
|
||||
|
||||
xmaxc[1] = (*c++ & 0x1F) << 1;
|
||||
xmaxc[1] |= (*c >> 7) & 0x1;
|
||||
|
||||
#undef xmc
|
||||
#define xmc (target + 29 - 13)
|
||||
|
||||
xmc[13] = (*c >> 4) & 0x7;
|
||||
xmc[14] = (*c >> 1) & 0x7;
|
||||
xmc[15] = (*c++ & 0x1) << 2;
|
||||
xmc[15] |= (*c >> 6) & 0x3;
|
||||
xmc[16] = (*c >> 3) & 0x7;
|
||||
xmc[17] = *c++ & 0x7;
|
||||
xmc[18] = (*c >> 5) & 0x7;
|
||||
xmc[19] = (*c >> 2) & 0x7;
|
||||
xmc[20] = (*c++ & 0x3) << 1;
|
||||
xmc[20] |= (*c >> 7) & 0x1;
|
||||
xmc[21] = (*c >> 4) & 0x7;
|
||||
xmc[22] = (*c >> 1) & 0x7;
|
||||
xmc[23] = (*c++ & 0x1) << 2;
|
||||
xmc[23] |= (*c >> 6) & 0x3;
|
||||
xmc[24] = (*c >> 3) & 0x7;
|
||||
xmc[25] = *c++ & 0x7;
|
||||
|
||||
Nc[2] = (*c >> 1) & 0x7F;
|
||||
|
||||
bc[2] = (*c++ & 0x1) << 1; /* 20 */
|
||||
bc[2] |= (*c >> 7) & 0x1;
|
||||
|
||||
Mc[2] = (*c >> 5) & 0x3;
|
||||
|
||||
xmaxc[2] = (*c++ & 0x1F) << 1;
|
||||
xmaxc[2] |= (*c >> 7) & 0x1;
|
||||
|
||||
#undef xmc
|
||||
#define xmc (target + 46 - 26)
|
||||
|
||||
xmc[26] = (*c >> 4) & 0x7;
|
||||
xmc[27] = (*c >> 1) & 0x7;
|
||||
xmc[28] = (*c++ & 0x1) << 2;
|
||||
xmc[28] |= (*c >> 6) & 0x3;
|
||||
xmc[29] = (*c >> 3) & 0x7;
|
||||
xmc[30] = *c++ & 0x7;
|
||||
xmc[31] = (*c >> 5) & 0x7;
|
||||
xmc[32] = (*c >> 2) & 0x7;
|
||||
xmc[33] = (*c++ & 0x3) << 1;
|
||||
xmc[33] |= (*c >> 7) & 0x1;
|
||||
xmc[34] = (*c >> 4) & 0x7;
|
||||
xmc[35] = (*c >> 1) & 0x7;
|
||||
xmc[36] = (*c++ & 0x1) << 2;
|
||||
xmc[36] |= (*c >> 6) & 0x3;
|
||||
xmc[37] = (*c >> 3) & 0x7;
|
||||
xmc[38] = *c++ & 0x7;
|
||||
|
||||
Nc[3] = (*c >> 1) & 0x7F;
|
||||
|
||||
bc[3] = (*c++ & 0x1) << 1;
|
||||
bc[3] |= (*c >> 7) & 0x1;
|
||||
|
||||
Mc[3] = (*c >> 5) & 0x3;
|
||||
|
||||
xmaxc[3] = (*c++ & 0x1F) << 1;
|
||||
xmaxc[3] |= (*c >> 7) & 0x1;
|
||||
|
||||
#undef xmc
|
||||
#define xmc (target + 63 - 39)
|
||||
|
||||
xmc[39] = (*c >> 4) & 0x7;
|
||||
xmc[40] = (*c >> 1) & 0x7;
|
||||
xmc[41] = (*c++ & 0x1) << 2;
|
||||
xmc[41] |= (*c >> 6) & 0x3;
|
||||
xmc[42] = (*c >> 3) & 0x7;
|
||||
xmc[43] = *c++ & 0x7; /* 30 */
|
||||
xmc[44] = (*c >> 5) & 0x7;
|
||||
xmc[45] = (*c >> 2) & 0x7;
|
||||
xmc[46] = (*c++ & 0x3) << 1;
|
||||
xmc[46] |= (*c >> 7) & 0x1;
|
||||
xmc[47] = (*c >> 4) & 0x7;
|
||||
xmc[48] = (*c >> 1) & 0x7;
|
||||
xmc[49] = (*c++ & 0x1) << 2;
|
||||
xmc[49] |= (*c >> 6) & 0x3;
|
||||
xmc[50] = (*c >> 3) & 0x7;
|
||||
xmc[51] = *c & 0x7; /* 33 */
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
515
utils/iaxclient/lib/gsm/src/gsm_implode.c
Normal file
515
utils/iaxclient/lib/gsm/src/gsm_implode.c
Normal file
|
@ -0,0 +1,515 @@
|
|||
/*
|
||||
* Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
|
||||
* Universitaet Berlin. See the accompanying file "COPYRIGHT" for
|
||||
* details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Header$ */
|
||||
|
||||
#include "private.h"
|
||||
|
||||
#include "gsm.h"
|
||||
#include "proto.h"
|
||||
|
||||
void gsm_implode P3((s, source, c), gsm s, gsm_signal * source, gsm_byte * c)
|
||||
{
|
||||
/* variable size index
|
||||
|
||||
GSM_MAGIC 4 -
|
||||
|
||||
LARc[0] 6 0
|
||||
LARc[1] 6 1
|
||||
LARc[2] 5 2
|
||||
LARc[3] 5 3
|
||||
LARc[4] 4 4
|
||||
LARc[5] 4 5
|
||||
LARc[6] 3 6
|
||||
LARc[7] 3 7
|
||||
|
||||
Nc[0] 7 8
|
||||
bc[0] 2 9
|
||||
Mc[0] 2 10
|
||||
xmaxc[0] 6 11
|
||||
xmc[0] 3 12
|
||||
xmc[1] 3 13
|
||||
xmc[2] 3 14
|
||||
xmc[3] 3 15
|
||||
xmc[4] 3 16
|
||||
xmc[5] 3 17
|
||||
xmc[6] 3 18
|
||||
xmc[7] 3 19
|
||||
xmc[8] 3 20
|
||||
xmc[9] 3 21
|
||||
xmc[10] 3 22
|
||||
xmc[11] 3 23
|
||||
xmc[12] 3 24
|
||||
|
||||
Nc[1] 7 25
|
||||
bc[1] 2 26
|
||||
Mc[1] 2 27
|
||||
xmaxc[1] 6 28
|
||||
xmc[13] 3 29
|
||||
xmc[14] 3 30
|
||||
xmc[15] 3 31
|
||||
xmc[16] 3 32
|
||||
xmc[17] 3 33
|
||||
xmc[18] 3 34
|
||||
xmc[19] 3 35
|
||||
xmc[20] 3 36
|
||||
xmc[21] 3 37
|
||||
xmc[22] 3 38
|
||||
xmc[23] 3 39
|
||||
xmc[24] 3 40
|
||||
xmc[25] 3 41
|
||||
|
||||
Nc[2] 7 42
|
||||
bc[2] 2 43
|
||||
Mc[2] 2 44
|
||||
xmaxc[2] 6 45
|
||||
xmc[26] 3 46
|
||||
xmc[27] 3 47
|
||||
xmc[28] 3 48
|
||||
xmc[29] 3 49
|
||||
xmc[30] 3 50
|
||||
xmc[31] 3 51
|
||||
xmc[32] 3 52
|
||||
xmc[33] 3 53
|
||||
xmc[34] 3 54
|
||||
xmc[35] 3 55
|
||||
xmc[36] 3 56
|
||||
xmc[37] 3 57
|
||||
xmc[38] 3 58
|
||||
|
||||
Nc[3] 7 59
|
||||
bc[3] 2 60
|
||||
Mc[3] 2 61
|
||||
xmaxc[3] 6 62
|
||||
xmc[39] 3 63
|
||||
xmc[40] 3 64
|
||||
xmc[41] 3 65
|
||||
xmc[42] 3 66
|
||||
xmc[43] 3 67
|
||||
xmc[44] 3 68
|
||||
xmc[45] 3 69
|
||||
xmc[46] 3 70
|
||||
xmc[47] 3 71
|
||||
xmc[48] 3 72
|
||||
xmc[49] 3 73
|
||||
xmc[50] 3 74
|
||||
xmc[51] 3 75
|
||||
*/
|
||||
|
||||
/* There are 76 parameters per frame. The first eight are
|
||||
* unique. The remaining 68 are four identical subframes of
|
||||
* 17 parameters each. gsm_implode converts from a representation
|
||||
* of these parameters as values in one array of signed words
|
||||
* to the "packed" version of a GSM frame.
|
||||
*/
|
||||
|
||||
# define LARc source
|
||||
# define Nc *((gsm_signal (*) [17])(source + 8))
|
||||
# define bc *((gsm_signal (*) [17])(source + 9))
|
||||
# define Mc *((gsm_signal (*) [17])(source + 10))
|
||||
# define xmaxc *((gsm_signal (*) [17])(source + 11))
|
||||
|
||||
#ifdef WAV49
|
||||
if (s->wav_fmt) {
|
||||
|
||||
uword sr = 0;
|
||||
if (s->frame_index == 0) {
|
||||
|
||||
sr = *c++;
|
||||
LARc[0] = sr & 0x3f; sr >>= 6;
|
||||
sr |= (uword)*c++ << 2;
|
||||
LARc[1] = sr & 0x3f; sr >>= 6;
|
||||
sr |= (uword)*c++ << 4;
|
||||
LARc[2] = sr & 0x1f; sr >>= 5;
|
||||
LARc[3] = sr & 0x1f; sr >>= 5;
|
||||
sr |= (uword)*c++ << 2;
|
||||
LARc[4] = sr & 0xf; sr >>= 4;
|
||||
LARc[5] = sr & 0xf; sr >>= 4;
|
||||
sr |= (uword)*c++ << 2; /* 5 */
|
||||
LARc[6] = sr & 0x7; sr >>= 3;
|
||||
LARc[7] = sr & 0x7; sr >>= 3;
|
||||
sr |= (uword)*c++ << 4;
|
||||
Nc[0] = sr & 0x7f; sr >>= 7;
|
||||
bc[0] = sr & 0x3; sr >>= 2;
|
||||
Mc[0] = sr & 0x3; sr >>= 2;
|
||||
sr |= (uword)*c++ << 1;
|
||||
xmaxc[0] = sr & 0x3f; sr >>= 6;
|
||||
#undef xmc
|
||||
#define xmc (source + 12)
|
||||
xmc[0] = sr & 0x7; sr >>= 3;
|
||||
sr = *c++;
|
||||
xmc[1] = sr & 0x7; sr >>= 3;
|
||||
xmc[2] = sr & 0x7; sr >>= 3;
|
||||
sr |= (uword)*c++ << 2;
|
||||
xmc[3] = sr & 0x7; sr >>= 3;
|
||||
xmc[4] = sr & 0x7; sr >>= 3;
|
||||
xmc[5] = sr & 0x7; sr >>= 3;
|
||||
sr |= (uword)*c++ << 1; /* 10 */
|
||||
xmc[6] = sr & 0x7; sr >>= 3;
|
||||
xmc[7] = sr & 0x7; sr >>= 3;
|
||||
xmc[8] = sr & 0x7; sr >>= 3;
|
||||
sr = *c++;
|
||||
xmc[9] = sr & 0x7; sr >>= 3;
|
||||
xmc[10] = sr & 0x7; sr >>= 3;
|
||||
sr |= (uword)*c++ << 2;
|
||||
xmc[11] = sr & 0x7; sr >>= 3;
|
||||
xmc[12] = sr & 0x7; sr >>= 3;
|
||||
sr |= (uword)*c++ << 4;
|
||||
Nc[1] = sr & 0x7f; sr >>= 7;
|
||||
bc[1] = sr & 0x3; sr >>= 2;
|
||||
Mc[1] = sr & 0x3; sr >>= 2;
|
||||
sr |= (uword)*c++ << 1;
|
||||
xmaxc[1] = sr & 0x3f; sr >>= 6;
|
||||
#undef xmc
|
||||
#define xmc (source + 29 - 13)
|
||||
xmc[13] = sr & 0x7; sr >>= 3;
|
||||
sr = *c++; /* 15 */
|
||||
xmc[14] = sr & 0x7; sr >>= 3;
|
||||
xmc[15] = sr & 0x7; sr >>= 3;
|
||||
sr |= (uword)*c++ << 2;
|
||||
xmc[16] = sr & 0x7; sr >>= 3;
|
||||
xmc[17] = sr & 0x7; sr >>= 3;
|
||||
xmc[18] = sr & 0x7; sr >>= 3;
|
||||
sr |= (uword)*c++ << 1;
|
||||
xmc[19] = sr & 0x7; sr >>= 3;
|
||||
xmc[20] = sr & 0x7; sr >>= 3;
|
||||
xmc[21] = sr & 0x7; sr >>= 3;
|
||||
sr = *c++;
|
||||
xmc[22] = sr & 0x7; sr >>= 3;
|
||||
xmc[23] = sr & 0x7; sr >>= 3;
|
||||
sr |= (uword)*c++ << 2;
|
||||
xmc[24] = sr & 0x7; sr >>= 3;
|
||||
xmc[25] = sr & 0x7; sr >>= 3;
|
||||
sr |= (uword)*c++ << 4; /* 20 */
|
||||
Nc[2] = sr & 0x7f; sr >>= 7;
|
||||
bc[2] = sr & 0x3; sr >>= 2;
|
||||
Mc[2] = sr & 0x3; sr >>= 2;
|
||||
sr |= (uword)*c++ << 1;
|
||||
xmaxc[2] = sr & 0x3f; sr >>= 6;
|
||||
#undef xmc
|
||||
#define xmc (source + 46 - 26)
|
||||
xmc[26] = sr & 0x7; sr >>= 3;
|
||||
sr = *c++;
|
||||
xmc[27] = sr & 0x7; sr >>= 3;
|
||||
xmc[28] = sr & 0x7; sr >>= 3;
|
||||
sr |= (uword)*c++ << 2;
|
||||
xmc[29] = sr & 0x7; sr >>= 3;
|
||||
xmc[30] = sr & 0x7; sr >>= 3;
|
||||
xmc[31] = sr & 0x7; sr >>= 3;
|
||||
sr |= (uword)*c++ << 1;
|
||||
xmc[32] = sr & 0x7; sr >>= 3;
|
||||
xmc[33] = sr & 0x7; sr >>= 3;
|
||||
xmc[34] = sr & 0x7; sr >>= 3;
|
||||
sr = *c++; /* 25 */
|
||||
xmc[35] = sr & 0x7; sr >>= 3;
|
||||
xmc[36] = sr & 0x7; sr >>= 3;
|
||||
sr |= (uword)*c++ << 2;
|
||||
xmc[37] = sr & 0x7; sr >>= 3;
|
||||
xmc[38] = sr & 0x7; sr >>= 3;
|
||||
sr |= (uword)*c++ << 4;
|
||||
Nc[3] = sr & 0x7f; sr >>= 7;
|
||||
bc[3] = sr & 0x3; sr >>= 2;
|
||||
Mc[3] = sr & 0x3; sr >>= 2;
|
||||
sr |= (uword)*c++ << 1;
|
||||
xmaxc[3] = sr & 0x3f; sr >>= 6;
|
||||
#undef xmc
|
||||
#define xmc (source + 63 - 39)
|
||||
|
||||
xmc[39] = sr & 0x7; sr >>= 3;
|
||||
sr = *c++;
|
||||
xmc[40] = sr & 0x7; sr >>= 3;
|
||||
xmc[41] = sr & 0x7; sr >>= 3;
|
||||
sr |= (uword)*c++ << 2; /* 30 */
|
||||
xmc[42] = sr & 0x7; sr >>= 3;
|
||||
xmc[43] = sr & 0x7; sr >>= 3;
|
||||
xmc[44] = sr & 0x7; sr >>= 3;
|
||||
sr |= (uword)*c++ << 1;
|
||||
xmc[45] = sr & 0x7; sr >>= 3;
|
||||
xmc[46] = sr & 0x7; sr >>= 3;
|
||||
xmc[47] = sr & 0x7; sr >>= 3;
|
||||
sr = *c++;
|
||||
xmc[48] = sr & 0x7; sr >>= 3;
|
||||
xmc[49] = sr & 0x7; sr >>= 3;
|
||||
sr |= (uword)*c++ << 2;
|
||||
xmc[50] = sr & 0x7; sr >>= 3;
|
||||
xmc[51] = sr & 0x7; sr >>= 3;
|
||||
|
||||
s->frame_chain = sr & 0xf;
|
||||
}
|
||||
else {
|
||||
sr = s->frame_chain;
|
||||
sr |= (uword)*c++ << 4; /* 1 */
|
||||
LARc[0] = sr & 0x3f; sr >>= 6;
|
||||
LARc[1] = sr & 0x3f; sr >>= 6;
|
||||
sr = *c++;
|
||||
LARc[2] = sr & 0x1f; sr >>= 5;
|
||||
sr |= (uword)*c++ << 3;
|
||||
LARc[3] = sr & 0x1f; sr >>= 5;
|
||||
LARc[4] = sr & 0xf; sr >>= 4;
|
||||
sr |= (uword)*c++ << 2;
|
||||
LARc[5] = sr & 0xf; sr >>= 4;
|
||||
LARc[6] = sr & 0x7; sr >>= 3;
|
||||
LARc[7] = sr & 0x7; sr >>= 3;
|
||||
sr = *c++; /* 5 */
|
||||
Nc[0] = sr & 0x7f; sr >>= 7;
|
||||
sr |= (uword)*c++ << 1;
|
||||
bc[0] = sr & 0x3; sr >>= 2;
|
||||
Mc[0] = sr & 0x3; sr >>= 2;
|
||||
sr |= (uword)*c++ << 5;
|
||||
xmaxc[0] = sr & 0x3f; sr >>= 6;
|
||||
#undef xmc
|
||||
#define xmc (source + 12)
|
||||
xmc[0] = sr & 0x7; sr >>= 3;
|
||||
xmc[1] = sr & 0x7; sr >>= 3;
|
||||
sr |= (uword)*c++ << 1;
|
||||
xmc[2] = sr & 0x7; sr >>= 3;
|
||||
xmc[3] = sr & 0x7; sr >>= 3;
|
||||
xmc[4] = sr & 0x7; sr >>= 3;
|
||||
sr = *c++;
|
||||
xmc[5] = sr & 0x7; sr >>= 3;
|
||||
xmc[6] = sr & 0x7; sr >>= 3;
|
||||
sr |= (uword)*c++ << 2; /* 10 */
|
||||
xmc[7] = sr & 0x7; sr >>= 3;
|
||||
xmc[8] = sr & 0x7; sr >>= 3;
|
||||
xmc[9] = sr & 0x7; sr >>= 3;
|
||||
sr |= (uword)*c++ << 1;
|
||||
xmc[10] = sr & 0x7; sr >>= 3;
|
||||
xmc[11] = sr & 0x7; sr >>= 3;
|
||||
xmc[12] = sr & 0x7; sr >>= 3;
|
||||
sr = *c++;
|
||||
Nc[1] = sr & 0x7f; sr >>= 7;
|
||||
sr |= (uword)*c++ << 1;
|
||||
bc[1] = sr & 0x3; sr >>= 2;
|
||||
Mc[1] = sr & 0x3; sr >>= 2;
|
||||
sr |= (uword)*c++ << 5;
|
||||
xmaxc[1] = sr & 0x3f; sr >>= 6;
|
||||
#undef xmc
|
||||
#define xmc (source + 29 - 13)
|
||||
xmc[13] = sr & 0x7; sr >>= 3;
|
||||
xmc[14] = sr & 0x7; sr >>= 3;
|
||||
sr |= (uword)*c++ << 1; /* 15 */
|
||||
xmc[15] = sr & 0x7; sr >>= 3;
|
||||
xmc[16] = sr & 0x7; sr >>= 3;
|
||||
xmc[17] = sr & 0x7; sr >>= 3;
|
||||
sr = *c++;
|
||||
xmc[18] = sr & 0x7; sr >>= 3;
|
||||
xmc[19] = sr & 0x7; sr >>= 3;
|
||||
sr |= (uword)*c++ << 2;
|
||||
xmc[20] = sr & 0x7; sr >>= 3;
|
||||
xmc[21] = sr & 0x7; sr >>= 3;
|
||||
xmc[22] = sr & 0x7; sr >>= 3;
|
||||
sr |= (uword)*c++ << 1;
|
||||
xmc[23] = sr & 0x7; sr >>= 3;
|
||||
xmc[24] = sr & 0x7; sr >>= 3;
|
||||
xmc[25] = sr & 0x7; sr >>= 3;
|
||||
sr = *c++;
|
||||
Nc[2] = sr & 0x7f; sr >>= 7;
|
||||
sr |= (uword)*c++ << 1; /* 20 */
|
||||
bc[2] = sr & 0x3; sr >>= 2;
|
||||
Mc[2] = sr & 0x3; sr >>= 2;
|
||||
sr |= (uword)*c++ << 5;
|
||||
xmaxc[2] = sr & 0x3f; sr >>= 6;
|
||||
#undef xmc
|
||||
#define xmc (source + 46 - 26)
|
||||
xmc[26] = sr & 0x7; sr >>= 3;
|
||||
xmc[27] = sr & 0x7; sr >>= 3;
|
||||
sr |= (uword)*c++ << 1;
|
||||
xmc[28] = sr & 0x7; sr >>= 3;
|
||||
xmc[29] = sr & 0x7; sr >>= 3;
|
||||
xmc[30] = sr & 0x7; sr >>= 3;
|
||||
sr = *c++;
|
||||
xmc[31] = sr & 0x7; sr >>= 3;
|
||||
xmc[32] = sr & 0x7; sr >>= 3;
|
||||
sr |= (uword)*c++ << 2;
|
||||
xmc[33] = sr & 0x7; sr >>= 3;
|
||||
xmc[34] = sr & 0x7; sr >>= 3;
|
||||
xmc[35] = sr & 0x7; sr >>= 3;
|
||||
sr |= (uword)*c++ << 1; /* 25 */
|
||||
xmc[36] = sr & 0x7; sr >>= 3;
|
||||
xmc[37] = sr & 0x7; sr >>= 3;
|
||||
xmc[38] = sr & 0x7; sr >>= 3;
|
||||
sr = *c++;
|
||||
Nc[3] = sr & 0x7f; sr >>= 7;
|
||||
sr |= (uword)*c++ << 1;
|
||||
bc[3] = sr & 0x3; sr >>= 2;
|
||||
Mc[3] = sr & 0x3; sr >>= 2;
|
||||
sr |= (uword)*c++ << 5;
|
||||
xmaxc[3] = sr & 0x3f; sr >>= 6;
|
||||
#undef xmc
|
||||
#define xmc (source + 63 - 39)
|
||||
|
||||
xmc[39] = sr & 0x7; sr >>= 3;
|
||||
xmc[40] = sr & 0x7; sr >>= 3;
|
||||
sr |= (uword)*c++ << 1;
|
||||
xmc[41] = sr & 0x7; sr >>= 3;
|
||||
xmc[42] = sr & 0x7; sr >>= 3;
|
||||
xmc[43] = sr & 0x7; sr >>= 3;
|
||||
sr = *c++; /* 30 */
|
||||
xmc[44] = sr & 0x7; sr >>= 3;
|
||||
xmc[45] = sr & 0x7; sr >>= 3;
|
||||
sr |= (uword)*c++ << 2;
|
||||
xmc[46] = sr & 0x7; sr >>= 3;
|
||||
xmc[47] = sr & 0x7; sr >>= 3;
|
||||
xmc[48] = sr & 0x7; sr >>= 3;
|
||||
sr |= (uword)*c++ << 1;
|
||||
xmc[49] = sr & 0x7; sr >>= 3;
|
||||
xmc[50] = sr & 0x7; sr >>= 3;
|
||||
xmc[51] = sr & 0x7; sr >>= 3;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
|
||||
*c++ = ((GSM_MAGIC & 0xF) << 4) /* 1 */
|
||||
| ((LARc[0] >> 2) & 0xF);
|
||||
*c++ = ((LARc[0] & 0x3) << 6)
|
||||
| (LARc[1] & 0x3F);
|
||||
*c++ = ((LARc[2] & 0x1F) << 3)
|
||||
| ((LARc[3] >> 2) & 0x7);
|
||||
*c++ = ((LARc[3] & 0x3) << 6)
|
||||
| ((LARc[4] & 0xF) << 2)
|
||||
| ((LARc[5] >> 2) & 0x3);
|
||||
*c++ = ((LARc[5] & 0x3) << 6)
|
||||
| ((LARc[6] & 0x7) << 3)
|
||||
| (LARc[7] & 0x7);
|
||||
|
||||
|
||||
*c++ = ((Nc[0] & 0x7F) << 1)
|
||||
|
||||
|
||||
| ((bc[0] >> 1) & 0x1);
|
||||
*c++ = ((bc[0] & 0x1) << 7)
|
||||
|
||||
|
||||
| ((Mc[0] & 0x3) << 5)
|
||||
|
||||
| ((xmaxc[0] >> 1) & 0x1F);
|
||||
*c++ = ((xmaxc[0] & 0x1) << 7)
|
||||
|
||||
#undef xmc
|
||||
#define xmc (source + 12)
|
||||
|
||||
| ((xmc[0] & 0x7) << 4)
|
||||
| ((xmc[1] & 0x7) << 1)
|
||||
| ((xmc[2] >> 2) & 0x1);
|
||||
*c++ = ((xmc[2] & 0x3) << 6)
|
||||
| ((xmc[3] & 0x7) << 3)
|
||||
| (xmc[4] & 0x7);
|
||||
*c++ = ((xmc[5] & 0x7) << 5) /* 10 */
|
||||
| ((xmc[6] & 0x7) << 2)
|
||||
| ((xmc[7] >> 1) & 0x3);
|
||||
*c++ = ((xmc[7] & 0x1) << 7)
|
||||
| ((xmc[8] & 0x7) << 4)
|
||||
| ((xmc[9] & 0x7) << 1)
|
||||
| ((xmc[10] >> 2) & 0x1);
|
||||
*c++ = ((xmc[10] & 0x3) << 6)
|
||||
| ((xmc[11] & 0x7) << 3)
|
||||
| (xmc[12] & 0x7);
|
||||
|
||||
|
||||
*c++ = ((Nc[1] & 0x7F) << 1)
|
||||
|
||||
|
||||
| ((bc[1] >> 1) & 0x1);
|
||||
*c++ = ((bc[1] & 0x1) << 7)
|
||||
|
||||
|
||||
| ((Mc[1] & 0x3) << 5)
|
||||
|
||||
|
||||
| ((xmaxc[1] >> 1) & 0x1F);
|
||||
*c++ = ((xmaxc[1] & 0x1) << 7)
|
||||
|
||||
#undef xmc
|
||||
#define xmc (source + 29 - 13)
|
||||
|
||||
| ((xmc[13] & 0x7) << 4)
|
||||
| ((xmc[14] & 0x7) << 1)
|
||||
| ((xmc[15] >> 2) & 0x1);
|
||||
*c++ = ((xmc[15] & 0x3) << 6)
|
||||
| ((xmc[16] & 0x7) << 3)
|
||||
| (xmc[17] & 0x7);
|
||||
*c++ = ((xmc[18] & 0x7) << 5)
|
||||
| ((xmc[19] & 0x7) << 2)
|
||||
| ((xmc[20] >> 1) & 0x3);
|
||||
*c++ = ((xmc[20] & 0x1) << 7)
|
||||
| ((xmc[21] & 0x7) << 4)
|
||||
| ((xmc[22] & 0x7) << 1)
|
||||
| ((xmc[23] >> 2) & 0x1);
|
||||
*c++ = ((xmc[23] & 0x3) << 6)
|
||||
| ((xmc[24] & 0x7) << 3)
|
||||
| (xmc[25] & 0x7);
|
||||
|
||||
|
||||
*c++ = ((Nc[2] & 0x7F) << 1) /* 20 */
|
||||
|
||||
|
||||
| ((bc[2] >> 1) & 0x1);
|
||||
*c++ = ((bc[2] & 0x1) << 7)
|
||||
|
||||
|
||||
| ((Mc[2] & 0x3) << 5)
|
||||
|
||||
|
||||
| ((xmaxc[2] >> 1) & 0x1F);
|
||||
*c++ = ((xmaxc[2] & 0x1) << 7)
|
||||
|
||||
#undef xmc
|
||||
#define xmc (source + 46 - 26)
|
||||
|
||||
| ((xmc[26] & 0x7) << 4)
|
||||
| ((xmc[27] & 0x7) << 1)
|
||||
| ((xmc[28] >> 2) & 0x1);
|
||||
*c++ = ((xmc[28] & 0x3) << 6)
|
||||
| ((xmc[29] & 0x7) << 3)
|
||||
| (xmc[30] & 0x7);
|
||||
*c++ = ((xmc[31] & 0x7) << 5)
|
||||
| ((xmc[32] & 0x7) << 2)
|
||||
| ((xmc[33] >> 1) & 0x3);
|
||||
*c++ = ((xmc[33] & 0x1) << 7)
|
||||
| ((xmc[34] & 0x7) << 4)
|
||||
| ((xmc[35] & 0x7) << 1)
|
||||
| ((xmc[36] >> 2) & 0x1);
|
||||
*c++ = ((xmc[36] & 0x3) << 6)
|
||||
| ((xmc[37] & 0x7) << 3)
|
||||
| (xmc[38] & 0x7);
|
||||
|
||||
|
||||
*c++ = ((Nc[3] & 0x7F) << 1)
|
||||
|
||||
|
||||
| ((bc[3] >> 1) & 0x1);
|
||||
*c++ = ((bc[3] & 0x1) << 7)
|
||||
|
||||
|
||||
| ((Mc[3] & 0x3) << 5)
|
||||
|
||||
|
||||
| ((xmaxc[3] >> 1) & 0x1F);
|
||||
*c++ = ((xmaxc[3] & 0x1) << 7)
|
||||
|
||||
#undef xmc
|
||||
#define xmc (source + 63 - 39)
|
||||
|
||||
| ((xmc[39] & 0x7) << 4)
|
||||
| ((xmc[40] & 0x7) << 1)
|
||||
| ((xmc[41] >> 2) & 0x1);
|
||||
*c++ = ((xmc[41] & 0x3) << 6) /* 30 */
|
||||
| ((xmc[42] & 0x7) << 3)
|
||||
| (xmc[43] & 0x7);
|
||||
*c++ = ((xmc[44] & 0x7) << 5)
|
||||
| ((xmc[45] & 0x7) << 2)
|
||||
| ((xmc[46] >> 1) & 0x3);
|
||||
*c++ = ((xmc[46] & 0x1) << 7)
|
||||
| ((xmc[47] & 0x7) << 4)
|
||||
| ((xmc[48] & 0x7) << 1)
|
||||
| ((xmc[49] >> 2) & 0x1);
|
||||
*c++ = ((xmc[49] & 0x3) << 6)
|
||||
| ((xmc[50] & 0x7) << 3)
|
||||
| (xmc[51] & 0x7);
|
||||
}
|
||||
}
|
69
utils/iaxclient/lib/gsm/src/gsm_option.c
Normal file
69
utils/iaxclient/lib/gsm/src/gsm_option.c
Normal file
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
|
||||
* Universitaet Berlin. See the accompanying file "COPYRIGHT" for
|
||||
* details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Header$ */
|
||||
|
||||
#include "private.h"
|
||||
|
||||
#include "gsm.h"
|
||||
#include "proto.h"
|
||||
|
||||
int gsm_option P3((r, opt, val), gsm r, int opt, int * val)
|
||||
{
|
||||
int result = -1;
|
||||
|
||||
switch (opt) {
|
||||
case GSM_OPT_LTP_CUT:
|
||||
#ifdef LTP_CUT
|
||||
result = r->ltp_cut;
|
||||
if (val) r->ltp_cut = *val;
|
||||
#endif
|
||||
break;
|
||||
|
||||
case GSM_OPT_VERBOSE:
|
||||
#ifndef NDEBUG
|
||||
result = r->verbose;
|
||||
if (val) r->verbose = *val;
|
||||
#endif
|
||||
break;
|
||||
|
||||
case GSM_OPT_FAST:
|
||||
|
||||
#if defined(FAST) && defined(USE_FLOAT_MUL)
|
||||
result = r->fast;
|
||||
if (val) r->fast = !!*val;
|
||||
#endif
|
||||
break;
|
||||
|
||||
case GSM_OPT_FRAME_CHAIN:
|
||||
|
||||
#ifdef WAV49
|
||||
result = r->frame_chain;
|
||||
if (val) r->frame_chain = *val;
|
||||
#endif
|
||||
break;
|
||||
|
||||
case GSM_OPT_FRAME_INDEX:
|
||||
|
||||
#ifdef WAV49
|
||||
result = r->frame_index;
|
||||
if (val) r->frame_index = *val;
|
||||
#endif
|
||||
break;
|
||||
|
||||
case GSM_OPT_WAV49:
|
||||
|
||||
#ifdef WAV49
|
||||
result = r->wav_fmt;
|
||||
if (val) r->wav_fmt = !!*val;
|
||||
#endif
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
167
utils/iaxclient/lib/gsm/src/gsm_print.c
Normal file
167
utils/iaxclient/lib/gsm/src/gsm_print.c
Normal file
|
@ -0,0 +1,167 @@
|
|||
/*
|
||||
* Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
|
||||
* Universitaet Berlin. See the accompanying file "COPYRIGHT" for
|
||||
* details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Header$ */
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "private.h"
|
||||
|
||||
#include "gsm.h"
|
||||
#include "proto.h"
|
||||
|
||||
int gsm_print P3((f, s, c), FILE * f, gsm s, gsm_byte * c)
|
||||
{
|
||||
word LARc[8], Nc[4], Mc[4], bc[4], xmaxc[4], xmc[13*4];
|
||||
|
||||
/* GSM_MAGIC = (*c >> 4) & 0xF; */
|
||||
|
||||
if (((*c >> 4) & 0x0F) != GSM_MAGIC) return -1;
|
||||
|
||||
LARc[0] = (*c++ & 0xF) << 2; /* 1 */
|
||||
LARc[0] |= (*c >> 6) & 0x3;
|
||||
LARc[1] = *c++ & 0x3F;
|
||||
LARc[2] = (*c >> 3) & 0x1F;
|
||||
LARc[3] = (*c++ & 0x7) << 2;
|
||||
LARc[3] |= (*c >> 6) & 0x3;
|
||||
LARc[4] = (*c >> 2) & 0xF;
|
||||
LARc[5] = (*c++ & 0x3) << 2;
|
||||
LARc[5] |= (*c >> 6) & 0x3;
|
||||
LARc[6] = (*c >> 3) & 0x7;
|
||||
LARc[7] = *c++ & 0x7;
|
||||
|
||||
|
||||
Nc[0] = (*c >> 1) & 0x7F;
|
||||
bc[0] = (*c++ & 0x1) << 1;
|
||||
bc[0] |= (*c >> 7) & 0x1;
|
||||
Mc[0] = (*c >> 5) & 0x3;
|
||||
xmaxc[0] = (*c++ & 0x1F) << 1;
|
||||
xmaxc[0] |= (*c >> 7) & 0x1;
|
||||
xmc[0] = (*c >> 4) & 0x7;
|
||||
xmc[1] = (*c >> 1) & 0x7;
|
||||
xmc[2] = (*c++ & 0x1) << 2;
|
||||
xmc[2] |= (*c >> 6) & 0x3;
|
||||
xmc[3] = (*c >> 3) & 0x7;
|
||||
xmc[4] = *c++ & 0x7;
|
||||
xmc[5] = (*c >> 5) & 0x7;
|
||||
xmc[6] = (*c >> 2) & 0x7;
|
||||
xmc[7] = (*c++ & 0x3) << 1; /* 10 */
|
||||
xmc[7] |= (*c >> 7) & 0x1;
|
||||
xmc[8] = (*c >> 4) & 0x7;
|
||||
xmc[9] = (*c >> 1) & 0x7;
|
||||
xmc[10] = (*c++ & 0x1) << 2;
|
||||
xmc[10] |= (*c >> 6) & 0x3;
|
||||
xmc[11] = (*c >> 3) & 0x7;
|
||||
xmc[12] = *c++ & 0x7;
|
||||
|
||||
Nc[1] = (*c >> 1) & 0x7F;
|
||||
bc[1] = (*c++ & 0x1) << 1;
|
||||
bc[1] |= (*c >> 7) & 0x1;
|
||||
Mc[1] = (*c >> 5) & 0x3;
|
||||
xmaxc[1] = (*c++ & 0x1F) << 1;
|
||||
xmaxc[1] |= (*c >> 7) & 0x1;
|
||||
xmc[13] = (*c >> 4) & 0x7;
|
||||
xmc[14] = (*c >> 1) & 0x7;
|
||||
xmc[15] = (*c++ & 0x1) << 2;
|
||||
xmc[15] |= (*c >> 6) & 0x3;
|
||||
xmc[16] = (*c >> 3) & 0x7;
|
||||
xmc[17] = *c++ & 0x7;
|
||||
xmc[18] = (*c >> 5) & 0x7;
|
||||
xmc[19] = (*c >> 2) & 0x7;
|
||||
xmc[20] = (*c++ & 0x3) << 1;
|
||||
xmc[20] |= (*c >> 7) & 0x1;
|
||||
xmc[21] = (*c >> 4) & 0x7;
|
||||
xmc[22] = (*c >> 1) & 0x7;
|
||||
xmc[23] = (*c++ & 0x1) << 2;
|
||||
xmc[23] |= (*c >> 6) & 0x3;
|
||||
xmc[24] = (*c >> 3) & 0x7;
|
||||
xmc[25] = *c++ & 0x7;
|
||||
|
||||
|
||||
Nc[2] = (*c >> 1) & 0x7F;
|
||||
bc[2] = (*c++ & 0x1) << 1; /* 20 */
|
||||
bc[2] |= (*c >> 7) & 0x1;
|
||||
Mc[2] = (*c >> 5) & 0x3;
|
||||
xmaxc[2] = (*c++ & 0x1F) << 1;
|
||||
xmaxc[2] |= (*c >> 7) & 0x1;
|
||||
xmc[26] = (*c >> 4) & 0x7;
|
||||
xmc[27] = (*c >> 1) & 0x7;
|
||||
xmc[28] = (*c++ & 0x1) << 2;
|
||||
xmc[28] |= (*c >> 6) & 0x3;
|
||||
xmc[29] = (*c >> 3) & 0x7;
|
||||
xmc[30] = *c++ & 0x7;
|
||||
xmc[31] = (*c >> 5) & 0x7;
|
||||
xmc[32] = (*c >> 2) & 0x7;
|
||||
xmc[33] = (*c++ & 0x3) << 1;
|
||||
xmc[33] |= (*c >> 7) & 0x1;
|
||||
xmc[34] = (*c >> 4) & 0x7;
|
||||
xmc[35] = (*c >> 1) & 0x7;
|
||||
xmc[36] = (*c++ & 0x1) << 2;
|
||||
xmc[36] |= (*c >> 6) & 0x3;
|
||||
xmc[37] = (*c >> 3) & 0x7;
|
||||
xmc[38] = *c++ & 0x7;
|
||||
|
||||
Nc[3] = (*c >> 1) & 0x7F;
|
||||
bc[3] = (*c++ & 0x1) << 1;
|
||||
bc[3] |= (*c >> 7) & 0x1;
|
||||
Mc[3] = (*c >> 5) & 0x3;
|
||||
xmaxc[3] = (*c++ & 0x1F) << 1;
|
||||
xmaxc[3] |= (*c >> 7) & 0x1;
|
||||
|
||||
xmc[39] = (*c >> 4) & 0x7;
|
||||
xmc[40] = (*c >> 1) & 0x7;
|
||||
xmc[41] = (*c++ & 0x1) << 2;
|
||||
xmc[41] |= (*c >> 6) & 0x3;
|
||||
xmc[42] = (*c >> 3) & 0x7;
|
||||
xmc[43] = *c++ & 0x7; /* 30 */
|
||||
xmc[44] = (*c >> 5) & 0x7;
|
||||
xmc[45] = (*c >> 2) & 0x7;
|
||||
xmc[46] = (*c++ & 0x3) << 1;
|
||||
xmc[46] |= (*c >> 7) & 0x1;
|
||||
xmc[47] = (*c >> 4) & 0x7;
|
||||
xmc[48] = (*c >> 1) & 0x7;
|
||||
xmc[49] = (*c++ & 0x1) << 2;
|
||||
xmc[49] |= (*c >> 6) & 0x3;
|
||||
xmc[50] = (*c >> 3) & 0x7;
|
||||
xmc[51] = *c & 0x7; /* 33 */
|
||||
|
||||
fprintf(f,
|
||||
"LARc:\t%2.2d %2.2d %2.2d %2.2d %2.2d %2.2d %2.2d %2.2d\n",
|
||||
LARc[0],LARc[1],LARc[2],LARc[3],LARc[4],LARc[5],LARc[6],LARc[7]);
|
||||
|
||||
fprintf(f, "#1: Nc %4.4d bc %d Mc %d xmaxc %d\n",
|
||||
Nc[0], bc[0], Mc[0], xmaxc[0]);
|
||||
fprintf(f,
|
||||
"\t%.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d\n",
|
||||
xmc[0],xmc[1],xmc[2],xmc[3],xmc[4],xmc[5],xmc[6],
|
||||
xmc[7],xmc[8],xmc[9],xmc[10],xmc[11],xmc[12] );
|
||||
|
||||
fprintf(f, "#2: Nc %4.4d bc %d Mc %d xmaxc %d\n",
|
||||
Nc[1], bc[1], Mc[1], xmaxc[1]);
|
||||
fprintf(f,
|
||||
"\t%.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d\n",
|
||||
xmc[13+0],xmc[13+1],xmc[13+2],xmc[13+3],xmc[13+4],xmc[13+5],
|
||||
xmc[13+6], xmc[13+7],xmc[13+8],xmc[13+9],xmc[13+10],xmc[13+11],
|
||||
xmc[13+12] );
|
||||
|
||||
fprintf(f, "#3: Nc %4.4d bc %d Mc %d xmaxc %d\n",
|
||||
Nc[2], bc[2], Mc[2], xmaxc[2]);
|
||||
fprintf(f,
|
||||
"\t%.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d\n",
|
||||
xmc[26+0],xmc[26+1],xmc[26+2],xmc[26+3],xmc[26+4],xmc[26+5],
|
||||
xmc[26+6], xmc[26+7],xmc[26+8],xmc[26+9],xmc[26+10],xmc[26+11],
|
||||
xmc[26+12] );
|
||||
|
||||
fprintf(f, "#4: Nc %4.4d bc %d Mc %d xmaxc %d\n",
|
||||
Nc[3], bc[3], Mc[3], xmaxc[3]);
|
||||
fprintf(f,
|
||||
"\t%.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d\n",
|
||||
xmc[39+0],xmc[39+1],xmc[39+2],xmc[39+3],xmc[39+4],xmc[39+5],
|
||||
xmc[39+6], xmc[39+7],xmc[39+8],xmc[39+9],xmc[39+10],xmc[39+11],
|
||||
xmc[39+12] );
|
||||
|
||||
return 0;
|
||||
}
|
84
utils/iaxclient/lib/gsm/src/k6opt.h
Normal file
84
utils/iaxclient/lib/gsm/src/k6opt.h
Normal file
|
@ -0,0 +1,84 @@
|
|||
/* k6opt.h vector functions optimized for MMX extensions to x86
|
||||
*
|
||||
* Copyright (C) 1999 by Stanley J. Brooks <stabro@megsinet.net>
|
||||
*
|
||||
* Any use of this software is permitted provided that this notice is not
|
||||
* removed and that neither the authors nor the Technische Universitaet Berlin
|
||||
* are deemed to have made any representations as to the suitability of this
|
||||
* software for any purpose nor are held responsible for any defects of
|
||||
* this software. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE;
|
||||
* not even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE.
|
||||
*
|
||||
* Chicago, 03.12.1999
|
||||
* Stanley J. Brooks
|
||||
*/
|
||||
|
||||
extern void Weighting_filter P2((e, x),
|
||||
const word * e, /* signal [-5..0.39.44] IN */
|
||||
word * x /* signal [0..39] OUT */
|
||||
)
|
||||
;
|
||||
|
||||
extern longword k6maxcc P3((wt,dp,Nc_out),
|
||||
const word *wt,
|
||||
const word *dp,
|
||||
word * Nc_out /* OUT */
|
||||
)
|
||||
;
|
||||
/*
|
||||
* k6maxmin(p,n,out[])
|
||||
* input p[n] is array of shorts (require n>0)
|
||||
* returns (long) maximum absolute value..
|
||||
* if out!=NULL, also returns out[0] the maximum and out[1] the minimum
|
||||
*/
|
||||
extern longword k6maxmin P3((p,n,out),
|
||||
const word *p,
|
||||
int n,
|
||||
word *out /* out[0] is max, out[1] is min */
|
||||
)
|
||||
;
|
||||
|
||||
extern longword k6iprod P3((p,q,n),
|
||||
const word *p,
|
||||
const word *q,
|
||||
int n
|
||||
)
|
||||
;
|
||||
|
||||
/*
|
||||
* k6vsraw(p,n,bits)
|
||||
* input p[n] is array of shorts (require n>0)
|
||||
* shift/round each to the right by bits>=0 bits.
|
||||
*/
|
||||
extern void k6vsraw P3((p,n,bits),
|
||||
const word *p,
|
||||
int n,
|
||||
int bits
|
||||
)
|
||||
;
|
||||
|
||||
/*
|
||||
* k6vsllw(p,n,bits)
|
||||
* input p[n] is array of shorts (require n>0)
|
||||
* shift each to the left by bits>=0 bits.
|
||||
*/
|
||||
extern void k6vsllw P3((p,n,bits),
|
||||
const word *p,
|
||||
int n,
|
||||
int bits
|
||||
)
|
||||
;
|
||||
|
||||
#if 1 /* there isn't any significant speed gain from mmx here: */
|
||||
extern void Short_term_analysis_filteringx P4((u0,rp0,k_n,s),
|
||||
register word * u0,
|
||||
register word * rp0, /* [0..7] IN */
|
||||
register int k_n, /* k_end - k_start */
|
||||
register word * s /* [0..n-1] IN/OUT */
|
||||
)
|
||||
;
|
||||
/*
|
||||
#define Short_term_analysis_filtering Short_term_analysis_filteringx
|
||||
*/
|
||||
#endif
|
755
utils/iaxclient/lib/gsm/src/k6opt.s
Normal file
755
utils/iaxclient/lib/gsm/src/k6opt.s
Normal file
|
@ -0,0 +1,755 @@
|
|||
/* k6opt.s vector functions optimized for MMX extensions to x86
|
||||
*
|
||||
* Copyright (C) 1999 by Stanley J. Brooks <stabro@megsinet.net>
|
||||
*
|
||||
* Any use of this software is permitted provided that this notice is not
|
||||
* removed and that neither the authors nor the Technische Universitaet Berlin
|
||||
* are deemed to have made any representations as to the suitability of this
|
||||
* software for any purpose nor are held responsible for any defects of
|
||||
* this software. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE;
|
||||
* not even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE.
|
||||
*
|
||||
* Chicago, 03.12.1999
|
||||
* Stanley J. Brooks
|
||||
*/
|
||||
|
||||
.file "k6opt.s"
|
||||
.version "01.01"
|
||||
/* gcc2_compiled.: */
|
||||
.section .rodata
|
||||
.align 4
|
||||
.type coefs,@object
|
||||
.size coefs,24
|
||||
coefs:
|
||||
.value -134
|
||||
.value -374
|
||||
.value 0
|
||||
.value 2054
|
||||
.value 5741
|
||||
.value 8192
|
||||
.value 5741
|
||||
.value 2054
|
||||
.value 0
|
||||
.value -374
|
||||
.value -134
|
||||
.value 0
|
||||
.text
|
||||
.align 4
|
||||
/* void Weighting_filter (const short *e, short *x) */
|
||||
.globl Weighting_filter
|
||||
.type Weighting_filter,@function
|
||||
Weighting_filter:
|
||||
pushl %ebp
|
||||
movl %esp,%ebp
|
||||
pushl %edi
|
||||
pushl %esi
|
||||
pushl %ebx
|
||||
movl 12(%ebp),%edi
|
||||
movl 8(%ebp),%ebx
|
||||
addl $-10,%ebx
|
||||
emms
|
||||
movl $0x1000,%eax; movd %eax,%mm5 /* for rounding */
|
||||
movq coefs,%mm1
|
||||
movq coefs+8,%mm2
|
||||
movq coefs+16,%mm3
|
||||
xorl %esi,%esi
|
||||
.p2align 2
|
||||
.L21:
|
||||
movq (%ebx,%esi,2),%mm0
|
||||
pmaddwd %mm1,%mm0
|
||||
|
||||
movq 8(%ebx,%esi,2),%mm4
|
||||
pmaddwd %mm2,%mm4
|
||||
paddd %mm4,%mm0
|
||||
|
||||
movq 16(%ebx,%esi,2),%mm4
|
||||
pmaddwd %mm3,%mm4
|
||||
paddd %mm4,%mm0
|
||||
|
||||
movq %mm0,%mm4
|
||||
punpckhdq %mm0,%mm4 /* mm4 has high int32 of mm0 dup'd */
|
||||
paddd %mm4,%mm0;
|
||||
|
||||
paddd %mm5,%mm0 /* add for roundoff */
|
||||
psrad $13,%mm0
|
||||
packssdw %mm0,%mm0
|
||||
movd %mm0,%eax /* ax has result */
|
||||
movw %ax,(%edi,%esi,2)
|
||||
incl %esi
|
||||
cmpl $39,%esi
|
||||
jle .L21
|
||||
emms
|
||||
popl %ebx
|
||||
popl %esi
|
||||
popl %edi
|
||||
leave
|
||||
ret
|
||||
.Lfe1:
|
||||
.size Weighting_filter,.Lfe1-Weighting_filter
|
||||
|
||||
.macro ccstep n
|
||||
.if \n
|
||||
movq \n(%edi),%mm1
|
||||
movq \n(%esi),%mm2
|
||||
.else
|
||||
movq (%edi),%mm1
|
||||
movq (%esi),%mm2
|
||||
.endif
|
||||
pmaddwd %mm2,%mm1
|
||||
paddd %mm1,%mm0
|
||||
.endm
|
||||
|
||||
.align 4
|
||||
/* long k6maxcc(const short *wt, const short *dp, short *Nc_out) */
|
||||
.globl k6maxcc
|
||||
.type k6maxcc,@function
|
||||
k6maxcc:
|
||||
pushl %ebp
|
||||
movl %esp,%ebp
|
||||
pushl %edi
|
||||
pushl %esi
|
||||
pushl %ebx
|
||||
emms
|
||||
movl 8(%ebp),%edi
|
||||
movl 12(%ebp),%esi
|
||||
movl $0,%edx /* will be maximum inner-product */
|
||||
movl $40,%ebx
|
||||
movl %ebx,%ecx /* will be index of max inner-product */
|
||||
subl $80,%esi
|
||||
.p2align 2
|
||||
.L41:
|
||||
movq (%edi),%mm0
|
||||
movq (%esi),%mm2
|
||||
pmaddwd %mm2,%mm0
|
||||
ccstep 8
|
||||
ccstep 16
|
||||
ccstep 24
|
||||
ccstep 32
|
||||
ccstep 40
|
||||
ccstep 48
|
||||
ccstep 56
|
||||
ccstep 64
|
||||
ccstep 72
|
||||
|
||||
movq %mm0,%mm1
|
||||
punpckhdq %mm0,%mm1 /* mm1 has high int32 of mm0 dup'd */
|
||||
paddd %mm1,%mm0;
|
||||
movd %mm0,%eax /* eax has result */
|
||||
|
||||
cmpl %edx,%eax
|
||||
jle .L40
|
||||
movl %eax,%edx
|
||||
movl %ebx,%ecx
|
||||
.p2align 2
|
||||
.L40:
|
||||
subl $2,%esi
|
||||
incl %ebx
|
||||
cmpl $120,%ebx
|
||||
jle .L41
|
||||
movl 16(%ebp),%eax
|
||||
movw %cx,(%eax)
|
||||
movl %edx,%eax
|
||||
emms
|
||||
popl %ebx
|
||||
popl %esi
|
||||
popl %edi
|
||||
leave
|
||||
ret
|
||||
.Lfe2:
|
||||
.size k6maxcc,.Lfe2-k6maxcc
|
||||
|
||||
|
||||
.align 4
|
||||
/* long k6iprod (const short *p, const short *q, int n) */
|
||||
.globl k6iprod
|
||||
.type k6iprod,@function
|
||||
k6iprod:
|
||||
pushl %ebp
|
||||
movl %esp,%ebp
|
||||
pushl %edi
|
||||
pushl %esi
|
||||
emms
|
||||
pxor %mm0,%mm0
|
||||
movl 8(%ebp),%esi
|
||||
movl 12(%ebp),%edi
|
||||
movl 16(%ebp),%eax
|
||||
leal -32(%esi,%eax,2),%edx /* edx = top - 32 */
|
||||
|
||||
cmpl %edx,%esi; ja .L202
|
||||
|
||||
.p2align 2
|
||||
.L201:
|
||||
ccstep 0
|
||||
ccstep 8
|
||||
ccstep 16
|
||||
ccstep 24
|
||||
|
||||
addl $32,%esi
|
||||
addl $32,%edi
|
||||
cmpl %edx,%esi; jbe .L201
|
||||
|
||||
.p2align 2
|
||||
.L202:
|
||||
addl $24,%edx /* now edx = top-8 */
|
||||
cmpl %edx,%esi; ja .L205
|
||||
|
||||
.p2align 2
|
||||
.L203:
|
||||
ccstep 0
|
||||
|
||||
addl $8,%esi
|
||||
addl $8,%edi
|
||||
cmpl %edx,%esi; jbe .L203
|
||||
|
||||
.p2align 2
|
||||
.L205:
|
||||
addl $4,%edx /* now edx = top-4 */
|
||||
cmpl %edx,%esi; ja .L207
|
||||
|
||||
movd (%edi),%mm1
|
||||
movd (%esi),%mm2
|
||||
pmaddwd %mm2,%mm1
|
||||
paddd %mm1,%mm0
|
||||
|
||||
addl $4,%esi
|
||||
addl $4,%edi
|
||||
|
||||
.p2align 2
|
||||
.L207:
|
||||
addl $2,%edx /* now edx = top-2 */
|
||||
cmpl %edx,%esi; ja .L209
|
||||
|
||||
movswl (%edi),%eax
|
||||
movd %eax,%mm1
|
||||
movswl (%esi),%eax
|
||||
movd %eax,%mm2
|
||||
pmaddwd %mm2,%mm1
|
||||
paddd %mm1,%mm0
|
||||
|
||||
.p2align 2
|
||||
.L209:
|
||||
movq %mm0,%mm1
|
||||
punpckhdq %mm0,%mm1 /* mm1 has high int32 of mm0 dup'd */
|
||||
paddd %mm1,%mm0;
|
||||
movd %mm0,%eax /* eax has result */
|
||||
|
||||
emms
|
||||
popl %esi
|
||||
popl %edi
|
||||
leave
|
||||
ret
|
||||
.Lfe3:
|
||||
.size k6iprod,.Lfe3-k6iprod
|
||||
|
||||
|
||||
.align 4
|
||||
/* void k6vsraw P3((short *p, int n, int bits) */
|
||||
.globl k6vsraw
|
||||
.type k6vsraw,@function
|
||||
k6vsraw:
|
||||
pushl %ebp
|
||||
movl %esp,%ebp
|
||||
pushl %esi
|
||||
movl 8(%ebp),%esi
|
||||
movl 16(%ebp),%ecx
|
||||
andl %ecx,%ecx; jle .L399
|
||||
movl 12(%ebp),%eax
|
||||
leal -16(%esi,%eax,2),%edx /* edx = top - 16 */
|
||||
emms
|
||||
movd %ecx,%mm3
|
||||
movq ones,%mm2
|
||||
psllw %mm3,%mm2; psrlw $1,%mm2
|
||||
cmpl %edx,%esi; ja .L306
|
||||
|
||||
.p2align 2
|
||||
.L302: /* 8 words per iteration */
|
||||
movq (%esi),%mm0
|
||||
movq 8(%esi),%mm1
|
||||
paddsw %mm2,%mm0
|
||||
psraw %mm3,%mm0;
|
||||
paddsw %mm2,%mm1
|
||||
psraw %mm3,%mm1;
|
||||
movq %mm0,(%esi)
|
||||
movq %mm1,8(%esi)
|
||||
addl $16,%esi
|
||||
cmpl %edx,%esi
|
||||
jbe .L302
|
||||
|
||||
.p2align 2
|
||||
.L306:
|
||||
addl $12,%edx /* now edx = top-4 */
|
||||
cmpl %edx,%esi; ja .L310
|
||||
|
||||
.p2align 2
|
||||
.L308: /* do up to 6 words, two at a time */
|
||||
movd (%esi),%mm0
|
||||
paddsw %mm2,%mm0
|
||||
psraw %mm3,%mm0;
|
||||
movd %mm0,(%esi)
|
||||
addl $4,%esi
|
||||
cmpl %edx,%esi
|
||||
jbe .L308
|
||||
|
||||
.p2align 2
|
||||
.L310:
|
||||
addl $2,%edx /* now edx = top-2 */
|
||||
cmpl %edx,%esi; ja .L315
|
||||
|
||||
movzwl (%esi),%eax
|
||||
movd %eax,%mm0
|
||||
paddsw %mm2,%mm0
|
||||
psraw %mm3,%mm0;
|
||||
movd %mm0,%eax
|
||||
movw %ax,(%esi)
|
||||
|
||||
.p2align 2
|
||||
.L315:
|
||||
emms
|
||||
.L399:
|
||||
popl %esi
|
||||
leave
|
||||
ret
|
||||
.Lfe4:
|
||||
.size k6vsraw,.Lfe4-k6vsraw
|
||||
|
||||
.align 4
|
||||
/* void k6vsllw P3((short *p, int n, int bits) */
|
||||
.globl k6vsllw
|
||||
.type k6vsllw,@function
|
||||
k6vsllw:
|
||||
pushl %ebp
|
||||
movl %esp,%ebp
|
||||
pushl %esi
|
||||
movl 8(%ebp),%esi
|
||||
movl 16(%ebp),%ecx
|
||||
andl %ecx,%ecx; jle .L499
|
||||
movl 12(%ebp),%eax
|
||||
leal -16(%esi,%eax,2),%edx /* edx = top - 16 */
|
||||
emms
|
||||
movd %ecx,%mm3
|
||||
cmpl %edx,%esi; ja .L406
|
||||
|
||||
.p2align 2
|
||||
.L402: /* 8 words per iteration */
|
||||
movq (%esi),%mm0
|
||||
movq 8(%esi),%mm1
|
||||
psllw %mm3,%mm0;
|
||||
psllw %mm3,%mm1;
|
||||
movq %mm0,(%esi)
|
||||
movq %mm1,8(%esi)
|
||||
addl $16,%esi
|
||||
cmpl %edx,%esi
|
||||
jbe .L402
|
||||
|
||||
.p2align 2
|
||||
.L406:
|
||||
addl $12,%edx /* now edx = top-4 */
|
||||
cmpl %edx,%esi; ja .L410
|
||||
|
||||
.p2align 2
|
||||
.L408: /* do up to 6 words, two at a time */
|
||||
movd (%esi),%mm0
|
||||
psllw %mm3,%mm0;
|
||||
movd %mm0,(%esi)
|
||||
addl $4,%esi
|
||||
cmpl %edx,%esi
|
||||
jbe .L408
|
||||
|
||||
.p2align 2
|
||||
.L410:
|
||||
addl $2,%edx /* now edx = top-2 */
|
||||
cmpl %edx,%esi; ja .L415
|
||||
|
||||
movzwl (%esi),%eax
|
||||
movd %eax,%mm0
|
||||
psllw %mm3,%mm0;
|
||||
movd %mm0,%eax
|
||||
movw %ax,(%esi)
|
||||
|
||||
.p2align 2
|
||||
.L415:
|
||||
emms
|
||||
.L499:
|
||||
popl %esi
|
||||
leave
|
||||
ret
|
||||
.Lfe5:
|
||||
.size k6vsllw,.Lfe5-k6vsllw
|
||||
|
||||
|
||||
.section .rodata
|
||||
.align 4
|
||||
.type extremes,@object
|
||||
.size extremes,8
|
||||
extremes:
|
||||
.long 0x80008000
|
||||
.long 0x7fff7fff
|
||||
.type ones,@object
|
||||
.size ones,8
|
||||
ones:
|
||||
.long 0x00010001
|
||||
.long 0x00010001
|
||||
|
||||
.text
|
||||
.align 4
|
||||
/* long k6maxmin (const short *p, int n, short *out) */
|
||||
.globl k6maxmin
|
||||
.type k6maxmin,@function
|
||||
k6maxmin:
|
||||
pushl %ebp
|
||||
movl %esp,%ebp
|
||||
pushl %esi
|
||||
emms
|
||||
movl 8(%ebp),%esi
|
||||
movl 12(%ebp),%eax
|
||||
leal -8(%esi,%eax,2),%edx
|
||||
|
||||
cmpl %edx,%esi
|
||||
jbe .L52
|
||||
movd extremes,%mm0
|
||||
movd extremes+4,%mm1
|
||||
jmp .L58
|
||||
|
||||
.p2align 2
|
||||
.L52:
|
||||
movq (%esi),%mm0 /* mm0 will be max's */
|
||||
movq %mm0,%mm1 /* mm1 will be min's */
|
||||
addl $8,%esi
|
||||
cmpl %edx,%esi
|
||||
ja .L56
|
||||
|
||||
.p2align 2
|
||||
.L54:
|
||||
movq (%esi),%mm2
|
||||
|
||||
movq %mm2,%mm3
|
||||
pcmpgtw %mm0,%mm3 /* mm3 is bitmask for words where mm2 > mm0 */
|
||||
movq %mm3,%mm4
|
||||
pand %mm2,%mm3 /* mm3 is mm2 masked to new max's */
|
||||
pandn %mm0,%mm4 /* mm4 is mm0 masked to its max's */
|
||||
por %mm3,%mm4
|
||||
movq %mm4,%mm0 /* now mm0 is updated max's */
|
||||
|
||||
movq %mm1,%mm3
|
||||
pcmpgtw %mm2,%mm3 /* mm3 is bitmask for words where mm2 < mm1 */
|
||||
pand %mm3,%mm2 /* mm2 is mm2 masked to new min's */
|
||||
pandn %mm1,%mm3 /* mm3 is mm1 masked to its min's */
|
||||
por %mm3,%mm2
|
||||
movq %mm2,%mm1 /* now mm1 is updated min's */
|
||||
|
||||
addl $8,%esi
|
||||
cmpl %edx,%esi
|
||||
jbe .L54
|
||||
|
||||
.p2align 2
|
||||
.L56: /* merge down the 4-word max/mins to lower 2 words */
|
||||
|
||||
movq %mm0,%mm2
|
||||
psrlq $32,%mm2
|
||||
movq %mm2,%mm3
|
||||
pcmpgtw %mm0,%mm3 /* mm3 is bitmask for words where mm2 > mm0 */
|
||||
pand %mm3,%mm2 /* mm2 is mm2 masked to new max's */
|
||||
pandn %mm0,%mm3 /* mm3 is mm0 masked to its max's */
|
||||
por %mm3,%mm2
|
||||
movq %mm2,%mm0 /* now mm0 is updated max's */
|
||||
|
||||
movq %mm1,%mm2
|
||||
psrlq $32,%mm2
|
||||
movq %mm1,%mm3
|
||||
pcmpgtw %mm2,%mm3 /* mm3 is bitmask for words where mm2 < mm1 */
|
||||
pand %mm3,%mm2 /* mm2 is mm2 masked to new min's */
|
||||
pandn %mm1,%mm3 /* mm3 is mm1 masked to its min's */
|
||||
por %mm3,%mm2
|
||||
movq %mm2,%mm1 /* now mm1 is updated min's */
|
||||
|
||||
.p2align 2
|
||||
.L58:
|
||||
addl $4,%edx /* now dx = top-4 */
|
||||
cmpl %edx,%esi
|
||||
ja .L62
|
||||
/* here, there are >= 2 words of input remaining */
|
||||
movd (%esi),%mm2
|
||||
|
||||
movq %mm2,%mm3
|
||||
pcmpgtw %mm0,%mm3 /* mm3 is bitmask for words where mm2 > mm0 */
|
||||
movq %mm3,%mm4
|
||||
pand %mm2,%mm3 /* mm3 is mm2 masked to new max's */
|
||||
pandn %mm0,%mm4 /* mm4 is mm0 masked to its max's */
|
||||
por %mm3,%mm4
|
||||
movq %mm4,%mm0 /* now mm0 is updated max's */
|
||||
|
||||
movq %mm1,%mm3
|
||||
pcmpgtw %mm2,%mm3 /* mm3 is bitmask for words where mm2 < mm1 */
|
||||
pand %mm3,%mm2 /* mm2 is mm2 masked to new min's */
|
||||
pandn %mm1,%mm3 /* mm3 is mm1 masked to its min's */
|
||||
por %mm3,%mm2
|
||||
movq %mm2,%mm1 /* now mm1 is updated min's */
|
||||
|
||||
addl $4,%esi
|
||||
|
||||
.p2align 2
|
||||
.L62:
|
||||
/* merge down the 2-word max/mins to 1 word */
|
||||
|
||||
movq %mm0,%mm2
|
||||
psrlq $16,%mm2
|
||||
movq %mm2,%mm3
|
||||
pcmpgtw %mm0,%mm3 /* mm3 is bitmask for words where mm2 > mm0 */
|
||||
pand %mm3,%mm2 /* mm2 is mm2 masked to new max's */
|
||||
pandn %mm0,%mm3 /* mm3 is mm0 masked to its max's */
|
||||
por %mm3,%mm2
|
||||
movd %mm2,%ecx /* cx is max so far */
|
||||
|
||||
movq %mm1,%mm2
|
||||
psrlq $16,%mm2
|
||||
movq %mm1,%mm3
|
||||
pcmpgtw %mm2,%mm3 /* mm3 is bitmask for words where mm2 < mm1 */
|
||||
pand %mm3,%mm2 /* mm2 is mm2 masked to new min's */
|
||||
pandn %mm1,%mm3 /* mm3 is mm1 masked to its min's */
|
||||
por %mm3,%mm2
|
||||
movd %mm2,%eax /* ax is min so far */
|
||||
|
||||
addl $2,%edx /* now dx = top-2 */
|
||||
cmpl %edx,%esi
|
||||
ja .L65
|
||||
|
||||
/* here, there is one word of input left */
|
||||
cmpw (%esi),%cx
|
||||
jge .L64
|
||||
movw (%esi),%cx
|
||||
.p2align 2
|
||||
.L64:
|
||||
cmpw (%esi),%ax
|
||||
jle .L65
|
||||
movw (%esi),%ax
|
||||
|
||||
.p2align 2
|
||||
.L65: /* (finally!) cx is the max, ax the min */
|
||||
movswl %cx,%ecx
|
||||
movswl %ax,%eax
|
||||
|
||||
movl 16(%ebp),%edx /* ptr to output max,min vals */
|
||||
andl %edx,%edx; jz .L77
|
||||
movw %cx,(%edx) /* max */
|
||||
movw %ax,2(%edx) /* min */
|
||||
.p2align 2
|
||||
.L77:
|
||||
/* now calculate max absolute val */
|
||||
negl %eax
|
||||
cmpl %ecx,%eax
|
||||
jge .L81
|
||||
movl %ecx,%eax
|
||||
.p2align 2
|
||||
.L81:
|
||||
emms
|
||||
popl %esi
|
||||
leave
|
||||
ret
|
||||
.Lfe6:
|
||||
.size k6maxmin,.Lfe6-k6maxmin
|
||||
|
||||
/* void Short_term_analysis_filtering (short *u0, const short *rp0, int kn, short *s) */
|
||||
.equiv pm_u0,8
|
||||
.equiv pm_rp0,12
|
||||
.equiv pm_kn,16
|
||||
.equiv pm_s,20
|
||||
.equiv lv_u_top,-4
|
||||
.equiv lv_s_top,-8
|
||||
.equiv lv_rp,-40 /* local version of rp0 with each word twice */
|
||||
.align 4
|
||||
.globl Short_term_analysis_filteringx
|
||||
.type Short_term_analysis_filteringx,@function
|
||||
Short_term_analysis_filteringx:
|
||||
pushl %ebp
|
||||
movl %esp,%ebp
|
||||
subl $40,%esp
|
||||
pushl %edi
|
||||
pushl %esi
|
||||
|
||||
movl pm_rp0(%ebp),%esi;
|
||||
leal lv_rp(%ebp),%edi;
|
||||
cld
|
||||
lodsw; stosw; stosw
|
||||
lodsw; stosw; stosw
|
||||
lodsw; stosw; stosw
|
||||
lodsw; stosw; stosw
|
||||
lodsw; stosw; stosw
|
||||
lodsw; stosw; stosw
|
||||
lodsw; stosw; stosw
|
||||
lodsw; stosw; stosw
|
||||
emms
|
||||
movl $0x4000,%eax;
|
||||
movd %eax,%mm4;
|
||||
punpckldq %mm4,%mm4 /* (0x00004000,0x00004000) for rounding dword product pairs */
|
||||
|
||||
movl pm_u0(%ebp),%eax
|
||||
addl $16,%eax
|
||||
movl %eax,lv_u_top(%ebp) /* UTOP */
|
||||
movl pm_s(%ebp),%edx /* edx is local s ptr throughout below */
|
||||
movl pm_kn(%ebp),%eax
|
||||
leal (%edx,%eax,2),%eax
|
||||
movl %eax,lv_s_top(%ebp)
|
||||
cmpl %eax,%edx
|
||||
jae .L179
|
||||
.p2align 2
|
||||
.L181:
|
||||
leal lv_rp(%ebp),%esi /* RP */
|
||||
movl pm_u0(%ebp),%edi /* U */
|
||||
movw (%edx),%ax /* (0,DI) */
|
||||
roll $16,%eax
|
||||
movw (%edx),%ax /* (DI,DI) */
|
||||
.p2align 2
|
||||
.L185: /* RP is %esi */
|
||||
movl %eax,%ecx
|
||||
movw (%edi),%ax /* (DI,U) */
|
||||
movd (%esi),%mm3 /* mm3 is (0,0,RP,RP) */
|
||||
movw %cx,(%edi)
|
||||
|
||||
movd %eax,%mm2 /* mm2 is (0,0,DI,U) */
|
||||
rorl $16,%eax
|
||||
movd %eax,%mm1 /* mm1 is (0,0,U,DI) */
|
||||
|
||||
movq %mm1,%mm0
|
||||
pmullw %mm3,%mm0
|
||||
pmulhw %mm3,%mm1
|
||||
punpcklwd %mm1,%mm0 /* mm0 is (RP*U,RP*DI) */
|
||||
paddd %mm4,%mm0 /* mm4 is 0x00004000,0x00004000 */
|
||||
psrad $15,%mm0 /* (RP*U,RP*DI) adjusted */
|
||||
packssdw %mm0,%mm0 /* (*,*,RP*U,RP*DI) adjusted and saturated to word */
|
||||
paddsw %mm2,%mm0 /* mm0 is (?,?, DI', U') */
|
||||
movd %mm0,%eax /* (DI,U') */
|
||||
|
||||
addl $2,%edi
|
||||
addl $4,%esi
|
||||
cmpl lv_u_top(%ebp),%edi
|
||||
jb .L185
|
||||
|
||||
rorl $16,%eax
|
||||
movw %ax,(%edx) /* last DI goes to *s */
|
||||
addl $2,%edx /* next s */
|
||||
cmpl lv_s_top(%ebp),%edx
|
||||
jb .L181
|
||||
.p2align 2
|
||||
.L179:
|
||||
emms
|
||||
popl %esi
|
||||
popl %edi
|
||||
leave
|
||||
ret
|
||||
.Lfe7:
|
||||
.size Short_term_analysis_filteringx,.Lfe7-Short_term_analysis_filteringx
|
||||
|
||||
.end
|
||||
|
||||
/* 'as' macro's seem to be case-insensitive */
|
||||
.macro STEP n
|
||||
.if \n
|
||||
movd \n(%esi),%mm3 /* mm3 is (0,0,RP,RP) */
|
||||
.else
|
||||
movd (%esi),%mm3 /* mm3 is (0,0,RP,RP) */
|
||||
.endif
|
||||
movq %mm5,%mm1;
|
||||
movd %mm4,%ecx; movw %cx,%ax /* (DI,U) */
|
||||
psllq $48,%mm1; psrlq $16,%mm4; por %mm1,%mm4
|
||||
psllq $48,%mm0; psrlq $16,%mm5; por %mm0,%mm5
|
||||
|
||||
movd %eax,%mm2 /* mm2 is (0,0,DI,U) */
|
||||
rorl $16,%eax
|
||||
movd %eax,%mm1 /* mm1 is (0,0,U,DI) */
|
||||
|
||||
movq %mm1,%mm0
|
||||
pmullw %mm3,%mm0
|
||||
pmulhw %mm3,%mm1
|
||||
punpcklwd %mm1,%mm0 /* mm0 is (RP*U,RP*DI) */
|
||||
paddd %mm6,%mm0 /* mm6 is 0x00004000,0x00004000 */
|
||||
psrad $15,%mm0 /* (RP*U,RP*DI) adjusted */
|
||||
packssdw %mm0,%mm0 /* (*,*,RP*U,RP*DI) adjusted and saturated to word */
|
||||
paddsw %mm2,%mm0 /* mm0 is (?,?, DI', U') */
|
||||
movd %mm0,%eax /* (DI,U') */
|
||||
.endm
|
||||
|
||||
/* void Short_term_analysis_filtering (short *u0, const short *rp0, int kn, short *s) */
|
||||
.equiv pm_u0,8
|
||||
.equiv pm_rp0,12
|
||||
.equiv pm_kn,16
|
||||
.equiv pm_s,20
|
||||
.equiv lv_rp_top,-4
|
||||
.equiv lv_s_top,-8
|
||||
.equiv lv_rp,-40 /* local version of rp0 with each word twice */
|
||||
.align 4
|
||||
.globl Short_term_analysis_filteringx
|
||||
.type Short_term_analysis_filteringx,@function
|
||||
Short_term_analysis_filteringx:
|
||||
pushl %ebp
|
||||
movl %esp,%ebp
|
||||
subl $56,%esp
|
||||
pushl %edi
|
||||
pushl %esi
|
||||
pushl %ebx
|
||||
|
||||
movl pm_rp0(%ebp),%esi;
|
||||
leal lv_rp(%ebp),%edi;
|
||||
cld
|
||||
lodsw; stosw; stosw
|
||||
lodsw; stosw; stosw
|
||||
lodsw; stosw; stosw
|
||||
lodsw; stosw; stosw
|
||||
lodsw; stosw; stosw
|
||||
lodsw; stosw; stosw
|
||||
lodsw; stosw; stosw
|
||||
lodsw; stosw; stosw
|
||||
movl %edi,lv_rp_top(%ebp)
|
||||
emms
|
||||
|
||||
movl $0x4000,%eax;
|
||||
movd %eax,%mm6;
|
||||
punpckldq %mm6,%mm6 /* (0x00004000,0x00004000) for rounding dword product pairs */
|
||||
|
||||
movl pm_u0(%ebp),%ebx
|
||||
movq (%ebx),%mm4; movq 8(%ebx),%mm5 /* the 8 u's */
|
||||
movl pm_s(%ebp),%edx /* edx is local s ptr throughout below */
|
||||
movl pm_kn(%ebp),%eax
|
||||
leal (%edx,%eax,2),%eax
|
||||
movl %eax,lv_s_top(%ebp)
|
||||
cmpl %eax,%edx
|
||||
jae .L179
|
||||
.p2align 2
|
||||
.L181:
|
||||
leal lv_rp(%ebp),%esi /* RP */
|
||||
movw (%edx),%ax /* (0,DI) */
|
||||
roll $16,%eax
|
||||
movw (%edx),%ax /* (DI,DI) */
|
||||
movd %eax,%mm0
|
||||
.p2align 2
|
||||
.L185: /* RP is %esi */
|
||||
step 0
|
||||
step 4
|
||||
step 8
|
||||
step 12
|
||||
/*
|
||||
step 16
|
||||
step 20
|
||||
step 24
|
||||
step 28
|
||||
*/
|
||||
addl $16,%esi
|
||||
cmpl lv_rp_top(%ebp),%esi
|
||||
jb .L185
|
||||
|
||||
rorl $16,%eax
|
||||
movw %ax,(%edx) /* last DI goes to *s */
|
||||
addl $2,%edx /* next s */
|
||||
cmpl lv_s_top(%ebp),%edx
|
||||
jb .L181
|
||||
.L179:
|
||||
movq %mm4,(%ebx); movq %mm5,8(%ebx) /* the 8 u's */
|
||||
emms
|
||||
popl %ebx
|
||||
popl %esi
|
||||
popl %edi
|
||||
leave
|
||||
ret
|
||||
.Lfe7:
|
||||
.size Short_term_analysis_filteringx,.Lfe7-Short_term_analysis_filteringx
|
||||
.ident "GCC: (GNU) 2.95.2 19991109 (Debian GNU/Linux)"
|
954
utils/iaxclient/lib/gsm/src/long_term.c
Normal file
954
utils/iaxclient/lib/gsm/src/long_term.c
Normal file
|
@ -0,0 +1,954 @@
|
|||
/*
|
||||
* Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
|
||||
* Universitaet Berlin. See the accompanying file "COPYRIGHT" for
|
||||
* details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Header$ */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "private.h"
|
||||
|
||||
#include "gsm.h"
|
||||
#include "proto.h"
|
||||
#ifdef K6OPT
|
||||
#include "k6opt.h"
|
||||
#endif
|
||||
/*
|
||||
* 4.2.11 .. 4.2.12 LONG TERM PREDICTOR (LTP) SECTION
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* This module computes the LTP gain (bc) and the LTP lag (Nc)
|
||||
* for the long term analysis filter. This is done by calculating a
|
||||
* maximum of the cross-correlation function between the current
|
||||
* sub-segment short term residual signal d[0..39] (output of
|
||||
* the short term analysis filter; for simplification the index
|
||||
* of this array begins at 0 and ends at 39 for each sub-segment of the
|
||||
* RPE-LTP analysis) and the previous reconstructed short term
|
||||
* residual signal dp[ -120 .. -1 ]. A dynamic scaling must be
|
||||
* performed to avoid overflow.
|
||||
*/
|
||||
|
||||
/* The next procedure exists in six versions. First two integer
|
||||
* version (if USE_FLOAT_MUL is not defined); then four floating
|
||||
* point versions, twice with proper scaling (USE_FLOAT_MUL defined),
|
||||
* once without (USE_FLOAT_MUL and FAST defined, and fast run-time
|
||||
* option used). Every pair has first a Cut version (see the -C
|
||||
* option to toast or the LTP_CUT option to gsm_option()), then the
|
||||
* uncut one. (For a detailed explanation of why this is altogether
|
||||
* a bad idea, see Henry Spencer and Geoff Collyer, ``#ifdef Considered
|
||||
* Harmful''.)
|
||||
*/
|
||||
|
||||
#ifndef USE_FLOAT_MUL
|
||||
|
||||
#ifdef LTP_CUT
|
||||
|
||||
static void Cut_Calculation_of_the_LTP_parameters P5((st, d,dp,bc_out,Nc_out),
|
||||
|
||||
struct gsm_state * st,
|
||||
|
||||
register word * d, /* [0..39] IN */
|
||||
register word * dp, /* [-120..-1] IN */
|
||||
word * bc_out, /* OUT */
|
||||
word * Nc_out /* OUT */
|
||||
)
|
||||
{
|
||||
register int k, lambda;
|
||||
word Nc, bc;
|
||||
word wt[40];
|
||||
|
||||
longword L_result;
|
||||
longword L_max, L_power;
|
||||
word R, S, dmax, scal, best_k;
|
||||
word ltp_cut;
|
||||
|
||||
register word temp, wt_k;
|
||||
|
||||
/* Search of the optimum scaling of d[0..39].
|
||||
*/
|
||||
dmax = 0;
|
||||
for (k = 0; k <= 39; k++) {
|
||||
temp = d[k];
|
||||
temp = GSM_ABS( temp );
|
||||
if (temp > dmax) {
|
||||
dmax = temp;
|
||||
best_k = k;
|
||||
}
|
||||
}
|
||||
temp = 0;
|
||||
if (dmax == 0) scal = 0;
|
||||
else {
|
||||
assert(dmax > 0);
|
||||
temp = gsm_norm( (longword)dmax << 16 );
|
||||
}
|
||||
if (temp > 6) scal = 0;
|
||||
else scal = 6 - temp;
|
||||
assert(scal >= 0);
|
||||
|
||||
/* Search for the maximum cross-correlation and coding of the LTP lag
|
||||
*/
|
||||
L_max = 0;
|
||||
Nc = 40; /* index for the maximum cross-correlation */
|
||||
wt_k = SASR(d[best_k], scal);
|
||||
|
||||
for (lambda = 40; lambda <= 120; lambda++) {
|
||||
L_result = (longword)wt_k * dp[best_k - lambda];
|
||||
if (L_result > L_max) {
|
||||
Nc = lambda;
|
||||
L_max = L_result;
|
||||
}
|
||||
}
|
||||
*Nc_out = Nc;
|
||||
L_max <<= 1;
|
||||
|
||||
/* Rescaling of L_max
|
||||
*/
|
||||
assert(scal <= 100 && scal >= -100);
|
||||
L_max = L_max >> (6 - scal); /* sub(6, scal) */
|
||||
|
||||
assert( Nc <= 120 && Nc >= 40);
|
||||
|
||||
/* Compute the power of the reconstructed short term residual
|
||||
* signal dp[..]
|
||||
*/
|
||||
L_power = 0;
|
||||
for (k = 0; k <= 39; k++) {
|
||||
|
||||
register longword L_temp;
|
||||
|
||||
L_temp = SASR( dp[k - Nc], 3 );
|
||||
L_power += L_temp * L_temp;
|
||||
}
|
||||
L_power <<= 1; /* from L_MULT */
|
||||
|
||||
/* Normalization of L_max and L_power
|
||||
*/
|
||||
|
||||
if (L_max <= 0) {
|
||||
*bc_out = 0;
|
||||
return;
|
||||
}
|
||||
if (L_max >= L_power) {
|
||||
*bc_out = 3;
|
||||
return;
|
||||
}
|
||||
|
||||
temp = gsm_norm( L_power );
|
||||
|
||||
R = SASR( L_max << temp, 16 );
|
||||
S = SASR( L_power << temp, 16 );
|
||||
|
||||
/* Coding of the LTP gain
|
||||
*/
|
||||
|
||||
/* Table 4.3a must be used to obtain the level DLB[i] for the
|
||||
* quantization of the LTP gain b to get the coded version bc.
|
||||
*/
|
||||
for (bc = 0; bc <= 2; bc++) if (R <= gsm_mult(S, gsm_DLB[bc])) break;
|
||||
*bc_out = bc;
|
||||
}
|
||||
|
||||
#endif /* LTP_CUT */
|
||||
|
||||
static void Calculation_of_the_LTP_parameters P4((d,dp,bc_out,Nc_out),
|
||||
register word * d, /* [0..39] IN */
|
||||
register word * dp, /* [-120..-1] IN */
|
||||
word * bc_out, /* OUT */
|
||||
word * Nc_out /* OUT */
|
||||
)
|
||||
{
|
||||
register int k, lambda;
|
||||
word Nc, bc;
|
||||
word wt[40];
|
||||
|
||||
longword L_max, L_power;
|
||||
word R, S, dmax, scal;
|
||||
register word temp;
|
||||
|
||||
/* Search of the optimum scaling of d[0..39].
|
||||
*/
|
||||
dmax = 0;
|
||||
|
||||
for (k = 0; k <= 39; k++) {
|
||||
temp = d[k];
|
||||
temp = GSM_ABS( temp );
|
||||
if (temp > dmax) dmax = temp;
|
||||
}
|
||||
|
||||
temp = 0;
|
||||
if (dmax == 0) scal = 0;
|
||||
else {
|
||||
assert(dmax > 0);
|
||||
temp = gsm_norm( (longword)dmax << 16 );
|
||||
}
|
||||
|
||||
if (temp > 6) scal = 0;
|
||||
else scal = 6 - temp;
|
||||
|
||||
assert(scal >= 0);
|
||||
|
||||
/* Initialization of a working array wt
|
||||
*/
|
||||
|
||||
for (k = 0; k <= 39; k++) wt[k] = SASR( d[k], scal );
|
||||
|
||||
/* Search for the maximum cross-correlation and coding of the LTP lag
|
||||
*/
|
||||
# ifdef K6OPT
|
||||
L_max = k6maxcc(wt,dp,&Nc);
|
||||
# else
|
||||
L_max = 0;
|
||||
Nc = 40; /* index for the maximum cross-correlation */
|
||||
|
||||
for (lambda = 40; lambda <= 120; lambda++) {
|
||||
|
||||
# undef STEP
|
||||
# define STEP(k) (longword)wt[k] * dp[k - lambda]
|
||||
|
||||
register longword L_result;
|
||||
|
||||
L_result = STEP(0) ; L_result += STEP(1) ;
|
||||
L_result += STEP(2) ; L_result += STEP(3) ;
|
||||
L_result += STEP(4) ; L_result += STEP(5) ;
|
||||
L_result += STEP(6) ; L_result += STEP(7) ;
|
||||
L_result += STEP(8) ; L_result += STEP(9) ;
|
||||
L_result += STEP(10) ; L_result += STEP(11) ;
|
||||
L_result += STEP(12) ; L_result += STEP(13) ;
|
||||
L_result += STEP(14) ; L_result += STEP(15) ;
|
||||
L_result += STEP(16) ; L_result += STEP(17) ;
|
||||
L_result += STEP(18) ; L_result += STEP(19) ;
|
||||
L_result += STEP(20) ; L_result += STEP(21) ;
|
||||
L_result += STEP(22) ; L_result += STEP(23) ;
|
||||
L_result += STEP(24) ; L_result += STEP(25) ;
|
||||
L_result += STEP(26) ; L_result += STEP(27) ;
|
||||
L_result += STEP(28) ; L_result += STEP(29) ;
|
||||
L_result += STEP(30) ; L_result += STEP(31) ;
|
||||
L_result += STEP(32) ; L_result += STEP(33) ;
|
||||
L_result += STEP(34) ; L_result += STEP(35) ;
|
||||
L_result += STEP(36) ; L_result += STEP(37) ;
|
||||
L_result += STEP(38) ; L_result += STEP(39) ;
|
||||
|
||||
if (L_result > L_max) {
|
||||
|
||||
Nc = lambda;
|
||||
L_max = L_result;
|
||||
}
|
||||
}
|
||||
# endif
|
||||
*Nc_out = Nc;
|
||||
|
||||
L_max <<= 1;
|
||||
|
||||
/* Rescaling of L_max
|
||||
*/
|
||||
assert(scal <= 100 && scal >= -100);
|
||||
L_max = L_max >> (6 - scal); /* sub(6, scal) */
|
||||
|
||||
assert( Nc <= 120 && Nc >= 40);
|
||||
|
||||
/* Compute the power of the reconstructed short term residual
|
||||
* signal dp[..]
|
||||
*/
|
||||
L_power = 0;
|
||||
for (k = 0; k <= 39; k++) {
|
||||
|
||||
register longword L_temp;
|
||||
|
||||
L_temp = SASR( dp[k - Nc], 3 );
|
||||
L_power += L_temp * L_temp;
|
||||
}
|
||||
L_power <<= 1; /* from L_MULT */
|
||||
|
||||
/* Normalization of L_max and L_power
|
||||
*/
|
||||
|
||||
if (L_max <= 0) {
|
||||
*bc_out = 0;
|
||||
return;
|
||||
}
|
||||
if (L_max >= L_power) {
|
||||
*bc_out = 3;
|
||||
return;
|
||||
}
|
||||
|
||||
temp = gsm_norm( L_power );
|
||||
|
||||
R = SASR( L_max << temp, 16 );
|
||||
S = SASR( L_power << temp, 16 );
|
||||
|
||||
/* Coding of the LTP gain
|
||||
*/
|
||||
|
||||
/* Table 4.3a must be used to obtain the level DLB[i] for the
|
||||
* quantization of the LTP gain b to get the coded version bc.
|
||||
*/
|
||||
for (bc = 0; bc <= 2; bc++) if (R <= gsm_mult(S, gsm_DLB[bc])) break;
|
||||
*bc_out = bc;
|
||||
}
|
||||
|
||||
#else /* USE_FLOAT_MUL */
|
||||
|
||||
#ifdef LTP_CUT
|
||||
|
||||
static void Cut_Calculation_of_the_LTP_parameters P5((st, d,dp,bc_out,Nc_out),
|
||||
struct gsm_state * st, /* IN */
|
||||
register word * d, /* [0..39] IN */
|
||||
register word * dp, /* [-120..-1] IN */
|
||||
word * bc_out, /* OUT */
|
||||
word * Nc_out /* OUT */
|
||||
)
|
||||
{
|
||||
register int k, lambda;
|
||||
word Nc, bc;
|
||||
word ltp_cut;
|
||||
|
||||
float wt_float[40];
|
||||
float dp_float_base[120], * dp_float = dp_float_base + 120;
|
||||
|
||||
longword L_max, L_power;
|
||||
word R, S, dmax, scal;
|
||||
register word temp;
|
||||
|
||||
/* Search of the optimum scaling of d[0..39].
|
||||
*/
|
||||
dmax = 0;
|
||||
|
||||
for (k = 0; k <= 39; k++) {
|
||||
temp = d[k];
|
||||
temp = GSM_ABS( temp );
|
||||
if (temp > dmax) dmax = temp;
|
||||
}
|
||||
|
||||
temp = 0;
|
||||
if (dmax == 0) scal = 0;
|
||||
else {
|
||||
assert(dmax > 0);
|
||||
temp = gsm_norm( (longword)dmax << 16 );
|
||||
}
|
||||
|
||||
if (temp > 6) scal = 0;
|
||||
else scal = 6 - temp;
|
||||
|
||||
assert(scal >= 0);
|
||||
ltp_cut = (longword)SASR(dmax, scal) * st->ltp_cut / 100;
|
||||
|
||||
|
||||
/* Initialization of a working array wt
|
||||
*/
|
||||
|
||||
for (k = 0; k < 40; k++) {
|
||||
register word w = SASR( d[k], scal );
|
||||
if (w < 0 ? w > -ltp_cut : w < ltp_cut) {
|
||||
wt_float[k] = 0.0;
|
||||
}
|
||||
else {
|
||||
wt_float[k] = w;
|
||||
}
|
||||
}
|
||||
for (k = -120; k < 0; k++) dp_float[k] = dp[k];
|
||||
|
||||
/* Search for the maximum cross-correlation and coding of the LTP lag
|
||||
*/
|
||||
L_max = 0;
|
||||
Nc = 40; /* index for the maximum cross-correlation */
|
||||
|
||||
for (lambda = 40; lambda <= 120; lambda += 9) {
|
||||
|
||||
/* Calculate L_result for l = lambda .. lambda + 9.
|
||||
*/
|
||||
register float *lp = dp_float - lambda;
|
||||
|
||||
register float W;
|
||||
register float a = lp[-8], b = lp[-7], c = lp[-6],
|
||||
d = lp[-5], e = lp[-4], f = lp[-3],
|
||||
g = lp[-2], h = lp[-1];
|
||||
register float E;
|
||||
register float S0 = 0, S1 = 0, S2 = 0, S3 = 0, S4 = 0,
|
||||
S5 = 0, S6 = 0, S7 = 0, S8 = 0;
|
||||
|
||||
# undef STEP
|
||||
# define STEP(K, a, b, c, d, e, f, g, h) \
|
||||
if ((W = wt_float[K]) != 0.0) { \
|
||||
E = W * a; S8 += E; \
|
||||
E = W * b; S7 += E; \
|
||||
E = W * c; S6 += E; \
|
||||
E = W * d; S5 += E; \
|
||||
E = W * e; S4 += E; \
|
||||
E = W * f; S3 += E; \
|
||||
E = W * g; S2 += E; \
|
||||
E = W * h; S1 += E; \
|
||||
a = lp[K]; \
|
||||
E = W * a; S0 += E; } else (a = lp[K])
|
||||
|
||||
# define STEP_A(K) STEP(K, a, b, c, d, e, f, g, h)
|
||||
# define STEP_B(K) STEP(K, b, c, d, e, f, g, h, a)
|
||||
# define STEP_C(K) STEP(K, c, d, e, f, g, h, a, b)
|
||||
# define STEP_D(K) STEP(K, d, e, f, g, h, a, b, c)
|
||||
# define STEP_E(K) STEP(K, e, f, g, h, a, b, c, d)
|
||||
# define STEP_F(K) STEP(K, f, g, h, a, b, c, d, e)
|
||||
# define STEP_G(K) STEP(K, g, h, a, b, c, d, e, f)
|
||||
# define STEP_H(K) STEP(K, h, a, b, c, d, e, f, g)
|
||||
|
||||
STEP_A( 0); STEP_B( 1); STEP_C( 2); STEP_D( 3);
|
||||
STEP_E( 4); STEP_F( 5); STEP_G( 6); STEP_H( 7);
|
||||
|
||||
STEP_A( 8); STEP_B( 9); STEP_C(10); STEP_D(11);
|
||||
STEP_E(12); STEP_F(13); STEP_G(14); STEP_H(15);
|
||||
|
||||
STEP_A(16); STEP_B(17); STEP_C(18); STEP_D(19);
|
||||
STEP_E(20); STEP_F(21); STEP_G(22); STEP_H(23);
|
||||
|
||||
STEP_A(24); STEP_B(25); STEP_C(26); STEP_D(27);
|
||||
STEP_E(28); STEP_F(29); STEP_G(30); STEP_H(31);
|
||||
|
||||
STEP_A(32); STEP_B(33); STEP_C(34); STEP_D(35);
|
||||
STEP_E(36); STEP_F(37); STEP_G(38); STEP_H(39);
|
||||
|
||||
if (S0 > L_max) { L_max = S0; Nc = lambda; }
|
||||
if (S1 > L_max) { L_max = S1; Nc = lambda + 1; }
|
||||
if (S2 > L_max) { L_max = S2; Nc = lambda + 2; }
|
||||
if (S3 > L_max) { L_max = S3; Nc = lambda + 3; }
|
||||
if (S4 > L_max) { L_max = S4; Nc = lambda + 4; }
|
||||
if (S5 > L_max) { L_max = S5; Nc = lambda + 5; }
|
||||
if (S6 > L_max) { L_max = S6; Nc = lambda + 6; }
|
||||
if (S7 > L_max) { L_max = S7; Nc = lambda + 7; }
|
||||
if (S8 > L_max) { L_max = S8; Nc = lambda + 8; }
|
||||
|
||||
}
|
||||
*Nc_out = Nc;
|
||||
|
||||
L_max <<= 1;
|
||||
|
||||
/* Rescaling of L_max
|
||||
*/
|
||||
assert(scal <= 100 && scal >= -100);
|
||||
L_max = L_max >> (6 - scal); /* sub(6, scal) */
|
||||
|
||||
assert( Nc <= 120 && Nc >= 40);
|
||||
|
||||
/* Compute the power of the reconstructed short term residual
|
||||
* signal dp[..]
|
||||
*/
|
||||
L_power = 0;
|
||||
for (k = 0; k <= 39; k++) {
|
||||
|
||||
register longword L_temp;
|
||||
|
||||
L_temp = SASR( dp[k - Nc], 3 );
|
||||
L_power += L_temp * L_temp;
|
||||
}
|
||||
L_power <<= 1; /* from L_MULT */
|
||||
|
||||
/* Normalization of L_max and L_power
|
||||
*/
|
||||
|
||||
if (L_max <= 0) {
|
||||
*bc_out = 0;
|
||||
return;
|
||||
}
|
||||
if (L_max >= L_power) {
|
||||
*bc_out = 3;
|
||||
return;
|
||||
}
|
||||
|
||||
temp = gsm_norm( L_power );
|
||||
|
||||
R = SASR( L_max << temp, 16 );
|
||||
S = SASR( L_power << temp, 16 );
|
||||
|
||||
/* Coding of the LTP gain
|
||||
*/
|
||||
|
||||
/* Table 4.3a must be used to obtain the level DLB[i] for the
|
||||
* quantization of the LTP gain b to get the coded version bc.
|
||||
*/
|
||||
for (bc = 0; bc <= 2; bc++) if (R <= gsm_mult(S, gsm_DLB[bc])) break;
|
||||
*bc_out = bc;
|
||||
}
|
||||
|
||||
#endif /* LTP_CUT */
|
||||
|
||||
static void Calculation_of_the_LTP_parameters P4((d,dp,bc_out,Nc_out),
|
||||
register word * d, /* [0..39] IN */
|
||||
register word * dp, /* [-120..-1] IN */
|
||||
word * bc_out, /* OUT */
|
||||
word * Nc_out /* OUT */
|
||||
)
|
||||
{
|
||||
register int k, lambda;
|
||||
word Nc, bc;
|
||||
|
||||
float wt_float[40];
|
||||
float dp_float_base[120], * dp_float = dp_float_base + 120;
|
||||
|
||||
longword L_max, L_power;
|
||||
word R, S, dmax, scal;
|
||||
register word temp;
|
||||
|
||||
/* Search of the optimum scaling of d[0..39].
|
||||
*/
|
||||
dmax = 0;
|
||||
|
||||
for (k = 0; k <= 39; k++) {
|
||||
temp = d[k];
|
||||
temp = GSM_ABS( temp );
|
||||
if (temp > dmax) dmax = temp;
|
||||
}
|
||||
|
||||
temp = 0;
|
||||
if (dmax == 0) scal = 0;
|
||||
else {
|
||||
assert(dmax > 0);
|
||||
temp = gsm_norm( (longword)dmax << 16 );
|
||||
}
|
||||
|
||||
if (temp > 6) scal = 0;
|
||||
else scal = 6 - temp;
|
||||
|
||||
assert(scal >= 0);
|
||||
|
||||
/* Initialization of a working array wt
|
||||
*/
|
||||
|
||||
for (k = 0; k < 40; k++) wt_float[k] = SASR( d[k], scal );
|
||||
for (k = -120; k < 0; k++) dp_float[k] = dp[k];
|
||||
|
||||
/* Search for the maximum cross-correlation and coding of the LTP lag
|
||||
*/
|
||||
L_max = 0;
|
||||
Nc = 40; /* index for the maximum cross-correlation */
|
||||
|
||||
for (lambda = 40; lambda <= 120; lambda += 9) {
|
||||
|
||||
/* Calculate L_result for l = lambda .. lambda + 9.
|
||||
*/
|
||||
register float *lp = dp_float - lambda;
|
||||
|
||||
register float W;
|
||||
register float a = lp[-8], b = lp[-7], c = lp[-6],
|
||||
d = lp[-5], e = lp[-4], f = lp[-3],
|
||||
g = lp[-2], h = lp[-1];
|
||||
register float E;
|
||||
register float S0 = 0, S1 = 0, S2 = 0, S3 = 0, S4 = 0,
|
||||
S5 = 0, S6 = 0, S7 = 0, S8 = 0;
|
||||
|
||||
# undef STEP
|
||||
# define STEP(K, a, b, c, d, e, f, g, h) \
|
||||
W = wt_float[K]; \
|
||||
E = W * a; S8 += E; \
|
||||
E = W * b; S7 += E; \
|
||||
E = W * c; S6 += E; \
|
||||
E = W * d; S5 += E; \
|
||||
E = W * e; S4 += E; \
|
||||
E = W * f; S3 += E; \
|
||||
E = W * g; S2 += E; \
|
||||
E = W * h; S1 += E; \
|
||||
a = lp[K]; \
|
||||
E = W * a; S0 += E
|
||||
|
||||
# define STEP_A(K) STEP(K, a, b, c, d, e, f, g, h)
|
||||
# define STEP_B(K) STEP(K, b, c, d, e, f, g, h, a)
|
||||
# define STEP_C(K) STEP(K, c, d, e, f, g, h, a, b)
|
||||
# define STEP_D(K) STEP(K, d, e, f, g, h, a, b, c)
|
||||
# define STEP_E(K) STEP(K, e, f, g, h, a, b, c, d)
|
||||
# define STEP_F(K) STEP(K, f, g, h, a, b, c, d, e)
|
||||
# define STEP_G(K) STEP(K, g, h, a, b, c, d, e, f)
|
||||
# define STEP_H(K) STEP(K, h, a, b, c, d, e, f, g)
|
||||
|
||||
STEP_A( 0); STEP_B( 1); STEP_C( 2); STEP_D( 3);
|
||||
STEP_E( 4); STEP_F( 5); STEP_G( 6); STEP_H( 7);
|
||||
|
||||
STEP_A( 8); STEP_B( 9); STEP_C(10); STEP_D(11);
|
||||
STEP_E(12); STEP_F(13); STEP_G(14); STEP_H(15);
|
||||
|
||||
STEP_A(16); STEP_B(17); STEP_C(18); STEP_D(19);
|
||||
STEP_E(20); STEP_F(21); STEP_G(22); STEP_H(23);
|
||||
|
||||
STEP_A(24); STEP_B(25); STEP_C(26); STEP_D(27);
|
||||
STEP_E(28); STEP_F(29); STEP_G(30); STEP_H(31);
|
||||
|
||||
STEP_A(32); STEP_B(33); STEP_C(34); STEP_D(35);
|
||||
STEP_E(36); STEP_F(37); STEP_G(38); STEP_H(39);
|
||||
|
||||
if (S0 > L_max) { L_max = S0; Nc = lambda; }
|
||||
if (S1 > L_max) { L_max = S1; Nc = lambda + 1; }
|
||||
if (S2 > L_max) { L_max = S2; Nc = lambda + 2; }
|
||||
if (S3 > L_max) { L_max = S3; Nc = lambda + 3; }
|
||||
if (S4 > L_max) { L_max = S4; Nc = lambda + 4; }
|
||||
if (S5 > L_max) { L_max = S5; Nc = lambda + 5; }
|
||||
if (S6 > L_max) { L_max = S6; Nc = lambda + 6; }
|
||||
if (S7 > L_max) { L_max = S7; Nc = lambda + 7; }
|
||||
if (S8 > L_max) { L_max = S8; Nc = lambda + 8; }
|
||||
}
|
||||
*Nc_out = Nc;
|
||||
|
||||
L_max <<= 1;
|
||||
|
||||
/* Rescaling of L_max
|
||||
*/
|
||||
assert(scal <= 100 && scal >= -100);
|
||||
L_max = L_max >> (6 - scal); /* sub(6, scal) */
|
||||
|
||||
assert( Nc <= 120 && Nc >= 40);
|
||||
|
||||
/* Compute the power of the reconstructed short term residual
|
||||
* signal dp[..]
|
||||
*/
|
||||
L_power = 0;
|
||||
for (k = 0; k <= 39; k++) {
|
||||
|
||||
register longword L_temp;
|
||||
|
||||
L_temp = SASR( dp[k - Nc], 3 );
|
||||
L_power += L_temp * L_temp;
|
||||
}
|
||||
L_power <<= 1; /* from L_MULT */
|
||||
|
||||
/* Normalization of L_max and L_power
|
||||
*/
|
||||
|
||||
if (L_max <= 0) {
|
||||
*bc_out = 0;
|
||||
return;
|
||||
}
|
||||
if (L_max >= L_power) {
|
||||
*bc_out = 3;
|
||||
return;
|
||||
}
|
||||
|
||||
temp = gsm_norm( L_power );
|
||||
|
||||
R = SASR( L_max << temp, 16 );
|
||||
S = SASR( L_power << temp, 16 );
|
||||
|
||||
/* Coding of the LTP gain
|
||||
*/
|
||||
|
||||
/* Table 4.3a must be used to obtain the level DLB[i] for the
|
||||
* quantization of the LTP gain b to get the coded version bc.
|
||||
*/
|
||||
for (bc = 0; bc <= 2; bc++) if (R <= gsm_mult(S, gsm_DLB[bc])) break;
|
||||
*bc_out = bc;
|
||||
}
|
||||
|
||||
#ifdef FAST
|
||||
#ifdef LTP_CUT
|
||||
|
||||
static void Cut_Fast_Calculation_of_the_LTP_parameters P5((st,
|
||||
d,dp,bc_out,Nc_out),
|
||||
struct gsm_state * st, /* IN */
|
||||
register word * d, /* [0..39] IN */
|
||||
register word * dp, /* [-120..-1] IN */
|
||||
word * bc_out, /* OUT */
|
||||
word * Nc_out /* OUT */
|
||||
)
|
||||
{
|
||||
register int k, lambda;
|
||||
register float wt_float;
|
||||
word Nc, bc;
|
||||
word wt_max, best_k, ltp_cut;
|
||||
|
||||
float dp_float_base[120], * dp_float = dp_float_base + 120;
|
||||
|
||||
register float L_result, L_max, L_power;
|
||||
|
||||
wt_max = 0;
|
||||
|
||||
for (k = 0; k < 40; ++k) {
|
||||
if ( d[k] > wt_max) wt_max = d[best_k = k];
|
||||
else if (-d[k] > wt_max) wt_max = -d[best_k = k];
|
||||
}
|
||||
|
||||
assert(wt_max >= 0);
|
||||
wt_float = (float)wt_max;
|
||||
|
||||
for (k = -120; k < 0; ++k) dp_float[k] = (float)dp[k];
|
||||
|
||||
/* Search for the maximum cross-correlation and coding of the LTP lag
|
||||
*/
|
||||
L_max = 0;
|
||||
Nc = 40; /* index for the maximum cross-correlation */
|
||||
|
||||
for (lambda = 40; lambda <= 120; lambda++) {
|
||||
L_result = wt_float * dp_float[best_k - lambda];
|
||||
if (L_result > L_max) {
|
||||
Nc = lambda;
|
||||
L_max = L_result;
|
||||
}
|
||||
}
|
||||
|
||||
*Nc_out = Nc;
|
||||
if (L_max <= 0.) {
|
||||
*bc_out = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Compute the power of the reconstructed short term residual
|
||||
* signal dp[..]
|
||||
*/
|
||||
dp_float -= Nc;
|
||||
L_power = 0;
|
||||
for (k = 0; k < 40; ++k) {
|
||||
register float f = dp_float[k];
|
||||
L_power += f * f;
|
||||
}
|
||||
|
||||
if (L_max >= L_power) {
|
||||
*bc_out = 3;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Coding of the LTP gain
|
||||
* Table 4.3a must be used to obtain the level DLB[i] for the
|
||||
* quantization of the LTP gain b to get the coded version bc.
|
||||
*/
|
||||
lambda = L_max / L_power * 32768.;
|
||||
for (bc = 0; bc <= 2; ++bc) if (lambda <= gsm_DLB[bc]) break;
|
||||
*bc_out = bc;
|
||||
}
|
||||
|
||||
#endif /* LTP_CUT */
|
||||
|
||||
static void Fast_Calculation_of_the_LTP_parameters P4((d,dp,bc_out,Nc_out),
|
||||
register word * d, /* [0..39] IN */
|
||||
register word * dp, /* [-120..-1] IN */
|
||||
word * bc_out, /* OUT */
|
||||
word * Nc_out /* OUT */
|
||||
)
|
||||
{
|
||||
register int k, lambda;
|
||||
word Nc, bc;
|
||||
|
||||
float wt_float[40];
|
||||
float dp_float_base[120], * dp_float = dp_float_base + 120;
|
||||
|
||||
register float L_max, L_power;
|
||||
|
||||
for (k = 0; k < 40; ++k) wt_float[k] = (float)d[k];
|
||||
for (k = -120; k < 0; ++k) dp_float[k] = (float)dp[k];
|
||||
|
||||
/* Search for the maximum cross-correlation and coding of the LTP lag
|
||||
*/
|
||||
L_max = 0;
|
||||
Nc = 40; /* index for the maximum cross-correlation */
|
||||
|
||||
for (lambda = 40; lambda <= 120; lambda += 9) {
|
||||
|
||||
/* Calculate L_result for l = lambda .. lambda + 9.
|
||||
*/
|
||||
register float *lp = dp_float - lambda;
|
||||
|
||||
register float W;
|
||||
register float a = lp[-8], b = lp[-7], c = lp[-6],
|
||||
d = lp[-5], e = lp[-4], f = lp[-3],
|
||||
g = lp[-2], h = lp[-1];
|
||||
register float E;
|
||||
register float S0 = 0, S1 = 0, S2 = 0, S3 = 0, S4 = 0,
|
||||
S5 = 0, S6 = 0, S7 = 0, S8 = 0;
|
||||
|
||||
# undef STEP
|
||||
# define STEP(K, a, b, c, d, e, f, g, h) \
|
||||
W = wt_float[K]; \
|
||||
E = W * a; S8 += E; \
|
||||
E = W * b; S7 += E; \
|
||||
E = W * c; S6 += E; \
|
||||
E = W * d; S5 += E; \
|
||||
E = W * e; S4 += E; \
|
||||
E = W * f; S3 += E; \
|
||||
E = W * g; S2 += E; \
|
||||
E = W * h; S1 += E; \
|
||||
a = lp[K]; \
|
||||
E = W * a; S0 += E
|
||||
|
||||
# define STEP_A(K) STEP(K, a, b, c, d, e, f, g, h)
|
||||
# define STEP_B(K) STEP(K, b, c, d, e, f, g, h, a)
|
||||
# define STEP_C(K) STEP(K, c, d, e, f, g, h, a, b)
|
||||
# define STEP_D(K) STEP(K, d, e, f, g, h, a, b, c)
|
||||
# define STEP_E(K) STEP(K, e, f, g, h, a, b, c, d)
|
||||
# define STEP_F(K) STEP(K, f, g, h, a, b, c, d, e)
|
||||
# define STEP_G(K) STEP(K, g, h, a, b, c, d, e, f)
|
||||
# define STEP_H(K) STEP(K, h, a, b, c, d, e, f, g)
|
||||
|
||||
STEP_A( 0); STEP_B( 1); STEP_C( 2); STEP_D( 3);
|
||||
STEP_E( 4); STEP_F( 5); STEP_G( 6); STEP_H( 7);
|
||||
|
||||
STEP_A( 8); STEP_B( 9); STEP_C(10); STEP_D(11);
|
||||
STEP_E(12); STEP_F(13); STEP_G(14); STEP_H(15);
|
||||
|
||||
STEP_A(16); STEP_B(17); STEP_C(18); STEP_D(19);
|
||||
STEP_E(20); STEP_F(21); STEP_G(22); STEP_H(23);
|
||||
|
||||
STEP_A(24); STEP_B(25); STEP_C(26); STEP_D(27);
|
||||
STEP_E(28); STEP_F(29); STEP_G(30); STEP_H(31);
|
||||
|
||||
STEP_A(32); STEP_B(33); STEP_C(34); STEP_D(35);
|
||||
STEP_E(36); STEP_F(37); STEP_G(38); STEP_H(39);
|
||||
|
||||
if (S0 > L_max) { L_max = S0; Nc = lambda; }
|
||||
if (S1 > L_max) { L_max = S1; Nc = lambda + 1; }
|
||||
if (S2 > L_max) { L_max = S2; Nc = lambda + 2; }
|
||||
if (S3 > L_max) { L_max = S3; Nc = lambda + 3; }
|
||||
if (S4 > L_max) { L_max = S4; Nc = lambda + 4; }
|
||||
if (S5 > L_max) { L_max = S5; Nc = lambda + 5; }
|
||||
if (S6 > L_max) { L_max = S6; Nc = lambda + 6; }
|
||||
if (S7 > L_max) { L_max = S7; Nc = lambda + 7; }
|
||||
if (S8 > L_max) { L_max = S8; Nc = lambda + 8; }
|
||||
}
|
||||
*Nc_out = Nc;
|
||||
|
||||
if (L_max <= 0.) {
|
||||
*bc_out = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Compute the power of the reconstructed short term residual
|
||||
* signal dp[..]
|
||||
*/
|
||||
dp_float -= Nc;
|
||||
L_power = 0;
|
||||
for (k = 0; k < 40; ++k) {
|
||||
register float f = dp_float[k];
|
||||
L_power += f * f;
|
||||
}
|
||||
|
||||
if (L_max >= L_power) {
|
||||
*bc_out = 3;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Coding of the LTP gain
|
||||
* Table 4.3a must be used to obtain the level DLB[i] for the
|
||||
* quantization of the LTP gain b to get the coded version bc.
|
||||
*/
|
||||
lambda = L_max / L_power * 32768.;
|
||||
for (bc = 0; bc <= 2; ++bc) if (lambda <= gsm_DLB[bc]) break;
|
||||
*bc_out = bc;
|
||||
}
|
||||
|
||||
#endif /* FAST */
|
||||
#endif /* USE_FLOAT_MUL */
|
||||
|
||||
|
||||
/* 4.2.12 */
|
||||
|
||||
static void Long_term_analysis_filtering P6((bc,Nc,dp,d,dpp,e),
|
||||
word bc, /* IN */
|
||||
word Nc, /* IN */
|
||||
register word * dp, /* previous d [-120..-1] IN */
|
||||
register word * d, /* d [0..39] IN */
|
||||
register word * dpp, /* estimate [0..39] OUT */
|
||||
register word * e /* long term res. signal [0..39] OUT */
|
||||
)
|
||||
/*
|
||||
* In this part, we have to decode the bc parameter to compute
|
||||
* the samples of the estimate dpp[0..39]. The decoding of bc needs the
|
||||
* use of table 4.3b. The long term residual signal e[0..39]
|
||||
* is then calculated to be fed to the RPE encoding section.
|
||||
*/
|
||||
{
|
||||
register int k;
|
||||
register longword ltmp;
|
||||
|
||||
# undef STEP
|
||||
# define STEP(BP) \
|
||||
for (k = 0; k <= 39; k++) { \
|
||||
dpp[k] = GSM_MULT_R( BP, dp[k - Nc]); \
|
||||
e[k] = (word) GSM_SUB( d[k], dpp[k] ); \
|
||||
}
|
||||
|
||||
switch (bc) {
|
||||
case 0: STEP( 3277 ); break;
|
||||
case 1: STEP( 11469 ); break;
|
||||
case 2: STEP( 21299 ); break;
|
||||
case 3: STEP( 32767 ); break;
|
||||
}
|
||||
}
|
||||
|
||||
void Gsm_Long_Term_Predictor P7((S,d,dp,e,dpp,Nc,bc), /* 4x for 160 samples */
|
||||
|
||||
struct gsm_state * S,
|
||||
|
||||
word * d, /* [0..39] residual signal IN */
|
||||
word * dp, /* [-120..-1] d' IN */
|
||||
|
||||
word * e, /* [0..39] OUT */
|
||||
word * dpp, /* [0..39] OUT */
|
||||
word * Nc, /* correlation lag OUT */
|
||||
word * bc /* gain factor OUT */
|
||||
)
|
||||
{
|
||||
assert( d ); assert( dp ); assert( e );
|
||||
assert( dpp); assert( Nc ); assert( bc );
|
||||
|
||||
#if defined(FAST) && defined(USE_FLOAT_MUL)
|
||||
if (S->fast)
|
||||
#if defined (LTP_CUT)
|
||||
if (S->ltp_cut)
|
||||
Cut_Fast_Calculation_of_the_LTP_parameters(S,
|
||||
d, dp, bc, Nc);
|
||||
else
|
||||
#endif /* LTP_CUT */
|
||||
Fast_Calculation_of_the_LTP_parameters(d, dp, bc, Nc );
|
||||
else
|
||||
#endif /* FAST & USE_FLOAT_MUL */
|
||||
#ifdef LTP_CUT
|
||||
if (S->ltp_cut)
|
||||
Cut_Calculation_of_the_LTP_parameters(S, d, dp, bc, Nc);
|
||||
else
|
||||
#endif
|
||||
Calculation_of_the_LTP_parameters(d, dp, bc, Nc);
|
||||
|
||||
Long_term_analysis_filtering( *bc, *Nc, dp, d, dpp, e );
|
||||
}
|
||||
|
||||
/* 4.3.2 */
|
||||
void Gsm_Long_Term_Synthesis_Filtering P5((S,Ncr,bcr,erp,drp),
|
||||
struct gsm_state * S,
|
||||
|
||||
word Ncr,
|
||||
word bcr,
|
||||
register word * erp, /* [0..39] IN */
|
||||
register word * drp /* [-120..-1] IN, [-120..40] OUT */
|
||||
)
|
||||
/*
|
||||
* This procedure uses the bcr and Ncr parameter to realize the
|
||||
* long term synthesis filtering. The decoding of bcr needs
|
||||
* table 4.3b.
|
||||
*/
|
||||
{
|
||||
register longword ltmp; /* for ADD */
|
||||
register int k;
|
||||
word brp, drpp, Nr;
|
||||
|
||||
/* Check the limits of Nr.
|
||||
*/
|
||||
Nr = Ncr < 40 || Ncr > 120 ? S->nrp : Ncr;
|
||||
S->nrp = Nr;
|
||||
assert(Nr >= 40 && Nr <= 120);
|
||||
|
||||
/* Decoding of the LTP gain bcr
|
||||
*/
|
||||
brp = gsm_QLB[ bcr ];
|
||||
|
||||
/* Computation of the reconstructed short term residual
|
||||
* signal drp[0..39]
|
||||
*/
|
||||
assert(brp != MIN_WORD);
|
||||
|
||||
for (k = 0; k <= 39; k++) {
|
||||
drpp = GSM_MULT_R( brp, drp[ k - Nr ] );
|
||||
drp[k] = GSM_ADD( erp[k], drpp );
|
||||
}
|
||||
|
||||
/*
|
||||
* Update of the reconstructed short term residual signal
|
||||
* drp[ -1..-120 ]
|
||||
*/
|
||||
|
||||
for (k = 0; k <= 119; k++) drp[ -120 + k ] = drp[ -80 + k ];
|
||||
}
|
371
utils/iaxclient/lib/gsm/src/lpc.c
Normal file
371
utils/iaxclient/lib/gsm/src/lpc.c
Normal file
|
@ -0,0 +1,371 @@
|
|||
/*
|
||||
* Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
|
||||
* Universitaet Berlin. See the accompanying file "COPYRIGHT" for
|
||||
* details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Header$ */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "private.h"
|
||||
|
||||
#include "gsm.h"
|
||||
#include "proto.h"
|
||||
|
||||
#ifdef K6OPT
|
||||
#include "k6opt.h"
|
||||
#endif
|
||||
|
||||
#undef P
|
||||
|
||||
/*
|
||||
* 4.2.4 .. 4.2.7 LPC ANALYSIS SECTION
|
||||
*/
|
||||
|
||||
/* 4.2.4 */
|
||||
|
||||
|
||||
static void Autocorrelation P2((s, L_ACF),
|
||||
word * s, /* [0..159] IN/OUT */
|
||||
longword * L_ACF) /* [0..8] OUT */
|
||||
/*
|
||||
* The goal is to compute the array L_ACF[k]. The signal s[i] must
|
||||
* be scaled in order to avoid an overflow situation.
|
||||
*/
|
||||
{
|
||||
register int k, i;
|
||||
|
||||
word temp, smax, scalauto;
|
||||
|
||||
#ifdef USE_FLOAT_MUL
|
||||
float float_s[160];
|
||||
#endif
|
||||
|
||||
/* Dynamic scaling of the array s[0..159]
|
||||
*/
|
||||
|
||||
/* Search for the maximum.
|
||||
*/
|
||||
#ifndef K6OPT
|
||||
smax = 0;
|
||||
for (k = 0; k <= 159; k++) {
|
||||
temp = GSM_ABS( s[k] );
|
||||
if (temp > smax) smax = temp;
|
||||
}
|
||||
#else
|
||||
{
|
||||
longword lmax;
|
||||
lmax = k6maxmin(s,160,NULL);
|
||||
smax = (lmax > MAX_WORD) ? MAX_WORD : lmax;
|
||||
}
|
||||
#endif
|
||||
/* Computation of the scaling factor.
|
||||
*/
|
||||
if (smax == 0) scalauto = 0;
|
||||
else {
|
||||
assert(smax > 0);
|
||||
scalauto = 4 - gsm_norm( (longword)smax << 16 );/* sub(4,..) */
|
||||
}
|
||||
|
||||
/* Scaling of the array s[0...159]
|
||||
*/
|
||||
|
||||
if (scalauto > 0) {
|
||||
# ifndef K6OPT
|
||||
|
||||
# ifdef USE_FLOAT_MUL
|
||||
# define SCALE(n) \
|
||||
case n: for (k = 0; k <= 159; k++) \
|
||||
float_s[k] = (float) \
|
||||
(s[k] = GSM_MULT_R(s[k], 16384 >> (n-1)));\
|
||||
break;
|
||||
# else
|
||||
# define SCALE(n) \
|
||||
case n: for (k = 0; k <= 159; k++) \
|
||||
s[k] = GSM_MULT_R( s[k], 16384 >> (n-1) );\
|
||||
break;
|
||||
# endif /* USE_FLOAT_MUL */
|
||||
|
||||
switch (scalauto) {
|
||||
SCALE(1)
|
||||
SCALE(2)
|
||||
SCALE(3)
|
||||
SCALE(4)
|
||||
}
|
||||
# undef SCALE
|
||||
|
||||
# else /* K6OPT */
|
||||
k6vsraw(s,160,scalauto);
|
||||
# endif
|
||||
}
|
||||
# ifdef USE_FLOAT_MUL
|
||||
else for (k = 0; k <= 159; k++) float_s[k] = (float) s[k];
|
||||
# endif
|
||||
|
||||
/* Compute the L_ACF[..].
|
||||
*/
|
||||
#ifndef K6OPT
|
||||
{
|
||||
# ifdef USE_FLOAT_MUL
|
||||
register float * sp = float_s;
|
||||
register float sl = *sp;
|
||||
|
||||
# define STEP(k) L_ACF[k] += (longword)(sl * sp[ -(k) ]);
|
||||
# else
|
||||
word * sp = s;
|
||||
word sl = *sp;
|
||||
|
||||
# define STEP(k) L_ACF[k] += ((longword)sl * sp[ -(k) ]);
|
||||
# endif
|
||||
|
||||
# define NEXTI sl = *++sp
|
||||
|
||||
|
||||
for (k = 9; k--; L_ACF[k] = 0) ;
|
||||
|
||||
STEP (0);
|
||||
NEXTI;
|
||||
STEP(0); STEP(1);
|
||||
NEXTI;
|
||||
STEP(0); STEP(1); STEP(2);
|
||||
NEXTI;
|
||||
STEP(0); STEP(1); STEP(2); STEP(3);
|
||||
NEXTI;
|
||||
STEP(0); STEP(1); STEP(2); STEP(3); STEP(4);
|
||||
NEXTI;
|
||||
STEP(0); STEP(1); STEP(2); STEP(3); STEP(4); STEP(5);
|
||||
NEXTI;
|
||||
STEP(0); STEP(1); STEP(2); STEP(3); STEP(4); STEP(5); STEP(6);
|
||||
NEXTI;
|
||||
STEP(0); STEP(1); STEP(2); STEP(3); STEP(4); STEP(5); STEP(6); STEP(7);
|
||||
|
||||
for (i = 8; i <= 159; i++) {
|
||||
|
||||
NEXTI;
|
||||
|
||||
STEP(0);
|
||||
STEP(1); STEP(2); STEP(3); STEP(4);
|
||||
STEP(5); STEP(6); STEP(7); STEP(8);
|
||||
}
|
||||
|
||||
for (k = 9; k--; L_ACF[k] <<= 1) ;
|
||||
|
||||
}
|
||||
|
||||
#else
|
||||
{
|
||||
int k;
|
||||
for (k=0; k<9; k++) {
|
||||
L_ACF[k] = 2*k6iprod(s,s+k,160-k);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/* Rescaling of the array s[0..159]
|
||||
*/
|
||||
if (scalauto > 0) {
|
||||
assert(scalauto <= 4);
|
||||
#ifndef K6OPT
|
||||
for (k = 160; k--; *s++ <<= scalauto) ;
|
||||
# else /* K6OPT */
|
||||
k6vsllw(s,160,scalauto);
|
||||
# endif
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(USE_FLOAT_MUL) && defined(FAST)
|
||||
|
||||
static void Fast_Autocorrelation P2((s, L_ACF),
|
||||
word * s, /* [0..159] IN/OUT */
|
||||
longword * L_ACF) /* [0..8] OUT */
|
||||
{
|
||||
register int k, i;
|
||||
float f_L_ACF[9];
|
||||
float scale;
|
||||
|
||||
float s_f[160];
|
||||
register float *sf = s_f;
|
||||
|
||||
for (i = 0; i < 160; ++i) sf[i] = s[i];
|
||||
for (k = 0; k <= 8; k++) {
|
||||
register float L_temp2 = 0;
|
||||
register float *sfl = sf - k;
|
||||
for (i = k; i < 160; ++i) L_temp2 += sf[i] * sfl[i];
|
||||
f_L_ACF[k] = L_temp2;
|
||||
}
|
||||
scale = MAX_LONGWORD / f_L_ACF[0];
|
||||
|
||||
for (k = 0; k <= 8; k++) {
|
||||
L_ACF[k] = f_L_ACF[k] * scale;
|
||||
}
|
||||
}
|
||||
#endif /* defined (USE_FLOAT_MUL) && defined (FAST) */
|
||||
|
||||
/* 4.2.5 */
|
||||
|
||||
static void Reflection_coefficients P2( (L_ACF, r),
|
||||
longword * L_ACF, /* 0...8 IN */
|
||||
register word * r /* 0...7 OUT */
|
||||
)
|
||||
{
|
||||
register int i, m, n;
|
||||
register word temp;
|
||||
register longword ltmp;
|
||||
word ACF[9]; /* 0..8 */
|
||||
word P[ 9]; /* 0..8 */
|
||||
word K[ 9]; /* 2..8 */
|
||||
|
||||
/* Schur recursion with 16 bits arithmetic.
|
||||
*/
|
||||
|
||||
if (L_ACF[0] == 0) {
|
||||
for (i = 8; i--; *r++ = 0) ;
|
||||
return;
|
||||
}
|
||||
|
||||
assert( L_ACF[0] != 0 );
|
||||
temp = gsm_norm( L_ACF[0] );
|
||||
|
||||
assert(temp >= 0 && temp < 32);
|
||||
|
||||
/* ? overflow ? */
|
||||
for (i = 0; i <= 8; i++) ACF[i] = SASR( L_ACF[i] << temp, 16 );
|
||||
|
||||
/* Initialize array P[..] and K[..] for the recursion.
|
||||
*/
|
||||
|
||||
for (i = 1; i <= 7; i++) K[ i ] = ACF[ i ];
|
||||
for (i = 0; i <= 8; i++) P[ i ] = ACF[ i ];
|
||||
|
||||
/* Compute reflection coefficients
|
||||
*/
|
||||
for (n = 1; n <= 8; n++, r++) {
|
||||
|
||||
temp = P[1];
|
||||
temp = GSM_ABS(temp);
|
||||
if (P[0] < temp) {
|
||||
for (i = n; i <= 8; i++) *r++ = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
*r = gsm_div( temp, P[0] );
|
||||
|
||||
assert(*r >= 0);
|
||||
if (P[1] > 0) *r = -*r; /* r[n] = sub(0, r[n]) */
|
||||
assert (*r != MIN_WORD);
|
||||
if (n == 8) return;
|
||||
|
||||
/* Schur recursion
|
||||
*/
|
||||
temp = GSM_MULT_R( P[1], *r );
|
||||
P[0] = GSM_ADD( P[0], temp );
|
||||
|
||||
for (m = 1; m <= 8 - n; m++) {
|
||||
temp = GSM_MULT_R( K[ m ], *r );
|
||||
P[m] = GSM_ADD( P[ m+1 ], temp );
|
||||
|
||||
temp = GSM_MULT_R( P[ m+1 ], *r );
|
||||
K[m] = GSM_ADD( K[ m ], temp );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 4.2.6 */
|
||||
|
||||
static void Transformation_to_Log_Area_Ratios P1((r),
|
||||
register word * r /* 0..7 IN/OUT */
|
||||
)
|
||||
/*
|
||||
* The following scaling for r[..] and LAR[..] has been used:
|
||||
*
|
||||
* r[..] = integer( real_r[..]*32768. ); -1 <= real_r < 1.
|
||||
* LAR[..] = integer( real_LAR[..] * 16384 );
|
||||
* with -1.625 <= real_LAR <= 1.625
|
||||
*/
|
||||
{
|
||||
register word temp;
|
||||
register int i;
|
||||
|
||||
|
||||
/* Computation of the LAR[0..7] from the r[0..7]
|
||||
*/
|
||||
for (i = 1; i <= 8; i++, r++) {
|
||||
|
||||
temp = *r;
|
||||
temp = GSM_ABS(temp);
|
||||
assert(temp >= 0);
|
||||
|
||||
if (temp < 22118) {
|
||||
temp >>= 1;
|
||||
} else if (temp < 31130) {
|
||||
assert( temp >= 11059 );
|
||||
temp -= 11059;
|
||||
} else {
|
||||
assert( temp >= 26112 );
|
||||
temp -= 26112;
|
||||
temp <<= 2;
|
||||
}
|
||||
|
||||
*r = *r < 0 ? -temp : temp;
|
||||
assert( *r != MIN_WORD );
|
||||
}
|
||||
}
|
||||
|
||||
/* 4.2.7 */
|
||||
|
||||
static void Quantization_and_coding P1((LAR),
|
||||
register word * LAR /* [0..7] IN/OUT */
|
||||
)
|
||||
{
|
||||
register word temp;
|
||||
longword ltmp;
|
||||
|
||||
|
||||
/* This procedure needs four tables; the following equations
|
||||
* give the optimum scaling for the constants:
|
||||
*
|
||||
* A[0..7] = integer( real_A[0..7] * 1024 )
|
||||
* B[0..7] = integer( real_B[0..7] * 512 )
|
||||
* MAC[0..7] = maximum of the LARc[0..7]
|
||||
* MIC[0..7] = minimum of the LARc[0..7]
|
||||
*/
|
||||
|
||||
# undef STEP
|
||||
# define STEP( A, B, MAC, MIC ) \
|
||||
temp = GSM_MULT( A, *LAR ); \
|
||||
temp = GSM_ADD( temp, B ); \
|
||||
temp = GSM_ADD( temp, 256 ); \
|
||||
temp = SASR( temp, 9 ); \
|
||||
*LAR = temp>MAC ? MAC - MIC : (temp<MIC ? 0 : temp - MIC); \
|
||||
LAR++;
|
||||
|
||||
STEP( 20480, 0, 31, -32 );
|
||||
STEP( 20480, 0, 31, -32 );
|
||||
STEP( 20480, 2048, 15, -16 );
|
||||
STEP( 20480, -2560, 15, -16 );
|
||||
|
||||
STEP( 13964, 94, 7, -8 );
|
||||
STEP( 15360, -1792, 7, -8 );
|
||||
STEP( 8534, -341, 3, -4 );
|
||||
STEP( 9036, -1144, 3, -4 );
|
||||
|
||||
# undef STEP
|
||||
}
|
||||
|
||||
void Gsm_LPC_Analysis P3((S, s,LARc),
|
||||
struct gsm_state *S,
|
||||
word * s, /* 0..159 signals IN/OUT */
|
||||
word * LARc) /* 0..7 LARc's OUT */
|
||||
{
|
||||
longword L_ACF[9];
|
||||
|
||||
#if defined(USE_FLOAT_MUL) && defined(FAST)
|
||||
if (S->fast) Fast_Autocorrelation (s, L_ACF );
|
||||
else
|
||||
#endif
|
||||
Autocorrelation (s, L_ACF );
|
||||
Reflection_coefficients (L_ACF, LARc );
|
||||
Transformation_to_Log_Area_Ratios (LARc);
|
||||
Quantization_and_coding (LARc);
|
||||
}
|
129
utils/iaxclient/lib/gsm/src/preprocess.c
Normal file
129
utils/iaxclient/lib/gsm/src/preprocess.c
Normal file
|
@ -0,0 +1,129 @@
|
|||
/*
|
||||
* Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
|
||||
* Universitaet Berlin. See the accompanying file "COPYRIGHT" for
|
||||
* details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Header$ */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "private.h"
|
||||
|
||||
#include "gsm.h"
|
||||
#include "proto.h"
|
||||
|
||||
/* 4.2.0 .. 4.2.3 PREPROCESSING SECTION
|
||||
*
|
||||
* After A-law to linear conversion (or directly from the
|
||||
* Ato D converter) the following scaling is assumed for
|
||||
* input to the RPE-LTP algorithm:
|
||||
*
|
||||
* in: 0.1.....................12
|
||||
* S.v.v.v.v.v.v.v.v.v.v.v.v.*.*.*
|
||||
*
|
||||
* Where S is the sign bit, v a valid bit, and * a "don't care" bit.
|
||||
* The original signal is called sop[..]
|
||||
*
|
||||
* out: 0.1................... 12
|
||||
* S.S.v.v.v.v.v.v.v.v.v.v.v.v.0.0
|
||||
*/
|
||||
|
||||
|
||||
void Gsm_Preprocess P3((S, s, so),
|
||||
struct gsm_state * S,
|
||||
word * s,
|
||||
word * so ) /* [0..159] IN/OUT */
|
||||
{
|
||||
|
||||
word z1 = S->z1;
|
||||
longword L_z2 = S->L_z2;
|
||||
word mp = S->mp;
|
||||
|
||||
word s1;
|
||||
|
||||
|
||||
word SO;
|
||||
|
||||
longword ltmp; /* for ADD */
|
||||
ulongword utmp; /* for L_ADD */
|
||||
|
||||
register int k = 160;
|
||||
|
||||
while (k--) {
|
||||
|
||||
/* 4.2.1 Downscaling of the input signal
|
||||
*/
|
||||
/* SO = SASR( *s, 3 ) << 2;*/
|
||||
SO = SASR( *s, 1 ) & ~3;
|
||||
s++;
|
||||
|
||||
assert (SO >= -0x4000); /* downscaled by */
|
||||
assert (SO <= 0x3FFC); /* previous routine. */
|
||||
|
||||
|
||||
/* 4.2.2 Offset compensation
|
||||
*
|
||||
* This part implements a high-pass filter and requires extended
|
||||
* arithmetic precision for the recursive part of this filter.
|
||||
* The input of this procedure is the array so[0...159] and the
|
||||
* output the array sof[ 0...159 ].
|
||||
*/
|
||||
/* Compute the non-recursive part
|
||||
*/
|
||||
|
||||
s1 = SO - z1; /* s1 = gsm_sub( *so, z1 ); */
|
||||
z1 = SO;
|
||||
|
||||
assert(s1 != MIN_WORD);
|
||||
|
||||
/* SJB Remark: float might be faster than the mess that follows */
|
||||
|
||||
/* Compute the recursive part
|
||||
*/
|
||||
|
||||
/* Execution of a 31 bv 16 bits multiplication
|
||||
*/
|
||||
{
|
||||
word msp, lsp;
|
||||
longword L_s2;
|
||||
longword L_temp;
|
||||
|
||||
L_s2 = s1;
|
||||
L_s2 <<= 15;
|
||||
#ifndef __GNUC__
|
||||
msp = SASR( L_z2, 15 );
|
||||
lsp = L_z2 & 0x7fff; /* gsm_L_sub(L_z2,(msp<<15)); */
|
||||
|
||||
L_s2 += GSM_MULT_R( lsp, 32735 );
|
||||
L_temp = (longword)msp * 32735; /* GSM_L_MULT(msp,32735) >> 1;*/
|
||||
L_z2 = GSM_L_ADD( L_temp, L_s2 );
|
||||
/* above does L_z2 = L_z2 * 0x7fd5/0x8000 + L_s2 */
|
||||
#else
|
||||
L_z2 = ((long long)L_z2*32735 + 0x4000)>>15;
|
||||
/* alternate (ansi) version of above line does slightly different rounding:
|
||||
* L_temp = L_z2 >> 9;
|
||||
* L_temp += L_temp >> 5;
|
||||
* L_temp = (++L_temp) >> 1;
|
||||
* L_z2 = L_z2 - L_temp;
|
||||
*/
|
||||
L_z2 = GSM_L_ADD(L_z2,L_s2);
|
||||
#endif
|
||||
/* Compute sof[k] with rounding
|
||||
*/
|
||||
L_temp = GSM_L_ADD( L_z2, 16384 );
|
||||
|
||||
/* 4.2.3 Preemphasis
|
||||
*/
|
||||
|
||||
msp = GSM_MULT_R( mp, -28180 );
|
||||
mp = SASR( L_temp, 15 );
|
||||
*so++ = GSM_ADD( mp, msp );
|
||||
}
|
||||
}
|
||||
|
||||
S->z1 = z1;
|
||||
S->L_z2 = L_z2;
|
||||
S->mp = mp;
|
||||
}
|
491
utils/iaxclient/lib/gsm/src/rpe.c
Normal file
491
utils/iaxclient/lib/gsm/src/rpe.c
Normal file
|
@ -0,0 +1,491 @@
|
|||
/*
|
||||
* Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
|
||||
* Universitaet Berlin. See the accompanying file "COPYRIGHT" for
|
||||
* details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Header$ */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "private.h"
|
||||
|
||||
#include "gsm.h"
|
||||
#include "proto.h"
|
||||
|
||||
/* 4.2.13 .. 4.2.17 RPE ENCODING SECTION
|
||||
*/
|
||||
|
||||
/* 4.2.13 */
|
||||
#ifdef K6OPT
|
||||
#include "k6opt.h"
|
||||
#else
|
||||
static void Weighting_filter P2((e, x),
|
||||
register word * e, /* signal [-5..0.39.44] IN */
|
||||
word * x /* signal [0..39] OUT */
|
||||
)
|
||||
/*
|
||||
* The coefficients of the weighting filter are stored in a table
|
||||
* (see table 4.4). The following scaling is used:
|
||||
*
|
||||
* H[0..10] = integer( real_H[ 0..10] * 8192 );
|
||||
*/
|
||||
{
|
||||
/* word wt[ 50 ]; */
|
||||
|
||||
register longword L_result;
|
||||
register int k /* , i */ ;
|
||||
|
||||
/* Initialization of a temporary working array wt[0...49]
|
||||
*/
|
||||
|
||||
/* for (k = 0; k <= 4; k++) wt[k] = 0;
|
||||
* for (k = 5; k <= 44; k++) wt[k] = *e++;
|
||||
* for (k = 45; k <= 49; k++) wt[k] = 0;
|
||||
*
|
||||
* (e[-5..-1] and e[40..44] are allocated by the caller,
|
||||
* are initially zero and are not written anywhere.)
|
||||
*/
|
||||
e -= 5;
|
||||
|
||||
/* Compute the signal x[0..39]
|
||||
*/
|
||||
for (k = 0; k <= 39; k++) {
|
||||
|
||||
L_result = 8192 >> 1;
|
||||
|
||||
/* for (i = 0; i <= 10; i++) {
|
||||
* L_temp = GSM_L_MULT( wt[k+i], gsm_H[i] );
|
||||
* L_result = GSM_L_ADD( L_result, L_temp );
|
||||
* }
|
||||
*/
|
||||
|
||||
#undef STEP
|
||||
#define STEP( i, H ) (e[ k + i ] * (longword)H)
|
||||
|
||||
/* Every one of these multiplications is done twice --
|
||||
* but I don't see an elegant way to optimize this.
|
||||
* Do you?
|
||||
*/
|
||||
|
||||
#ifdef STUPID_COMPILER
|
||||
L_result += STEP( 0, -134 ) ;
|
||||
L_result += STEP( 1, -374 ) ;
|
||||
/* + STEP( 2, 0 ) */
|
||||
L_result += STEP( 3, 2054 ) ;
|
||||
L_result += STEP( 4, 5741 ) ;
|
||||
L_result += STEP( 5, 8192 ) ;
|
||||
L_result += STEP( 6, 5741 ) ;
|
||||
L_result += STEP( 7, 2054 ) ;
|
||||
/* + STEP( 8, 0 ) */
|
||||
L_result += STEP( 9, -374 ) ;
|
||||
L_result += STEP( 10, -134 ) ;
|
||||
#else
|
||||
L_result +=
|
||||
STEP( 0, -134 )
|
||||
+ STEP( 1, -374 )
|
||||
/* + STEP( 2, 0 ) */
|
||||
+ STEP( 3, 2054 )
|
||||
+ STEP( 4, 5741 )
|
||||
+ STEP( 5, 8192 )
|
||||
+ STEP( 6, 5741 )
|
||||
+ STEP( 7, 2054 )
|
||||
/* + STEP( 8, 0 ) */
|
||||
+ STEP( 9, -374 )
|
||||
+ STEP(10, -134 )
|
||||
;
|
||||
#endif
|
||||
|
||||
/* L_result = GSM_L_ADD( L_result, L_result ); (* scaling(x2) *)
|
||||
* L_result = GSM_L_ADD( L_result, L_result ); (* scaling(x4) *)
|
||||
*
|
||||
* x[k] = SASR( L_result, 16 );
|
||||
*/
|
||||
|
||||
/* 2 adds vs. >>16 => 14, minus one shift to compensate for
|
||||
* those we lost when replacing L_MULT by '*'.
|
||||
*/
|
||||
|
||||
L_result = SASR( L_result, 13 );
|
||||
x[k] = (word) (L_result < MIN_WORD ? MIN_WORD
|
||||
: (L_result > MAX_WORD ? MAX_WORD : L_result));
|
||||
}
|
||||
}
|
||||
#endif /* K6OPT */
|
||||
|
||||
/* 4.2.14 */
|
||||
|
||||
static void RPE_grid_selection P3((x,xM,Mc_out),
|
||||
word * x, /* [0..39] IN */
|
||||
word * xM, /* [0..12] OUT */
|
||||
word * Mc_out /* OUT */
|
||||
)
|
||||
/*
|
||||
* The signal x[0..39] is used to select the RPE grid which is
|
||||
* represented by Mc.
|
||||
*/
|
||||
{
|
||||
/* register word temp1; */
|
||||
register int /* m, */ i;
|
||||
register longword L_result, L_temp;
|
||||
longword EM; /* xxx should be L_EM? */
|
||||
word Mc;
|
||||
|
||||
longword L_common_0_3;
|
||||
|
||||
EM = 0;
|
||||
Mc = 0;
|
||||
|
||||
/* for (m = 0; m <= 3; m++) {
|
||||
* L_result = 0;
|
||||
*
|
||||
*
|
||||
* for (i = 0; i <= 12; i++) {
|
||||
*
|
||||
* temp1 = SASR( x[m + 3*i], 2 );
|
||||
*
|
||||
* assert(temp1 != MIN_WORD);
|
||||
*
|
||||
* L_temp = GSM_L_MULT( temp1, temp1 );
|
||||
* L_result = GSM_L_ADD( L_temp, L_result );
|
||||
* }
|
||||
*
|
||||
* if (L_result > EM) {
|
||||
* Mc = m;
|
||||
* EM = L_result;
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
|
||||
#undef STEP
|
||||
#define STEP( m, i ) L_temp = SASR( x[m + 3 * i], 2 ); \
|
||||
L_result += L_temp * L_temp;
|
||||
|
||||
/* common part of 0 and 3 */
|
||||
|
||||
L_result = 0;
|
||||
STEP( 0, 1 ); STEP( 0, 2 ); STEP( 0, 3 ); STEP( 0, 4 );
|
||||
STEP( 0, 5 ); STEP( 0, 6 ); STEP( 0, 7 ); STEP( 0, 8 );
|
||||
STEP( 0, 9 ); STEP( 0, 10); STEP( 0, 11); STEP( 0, 12);
|
||||
L_common_0_3 = L_result;
|
||||
|
||||
/* i = 0 */
|
||||
|
||||
STEP( 0, 0 );
|
||||
L_result <<= 1; /* implicit in L_MULT */
|
||||
EM = L_result;
|
||||
|
||||
/* i = 1 */
|
||||
|
||||
L_result = 0;
|
||||
STEP( 1, 0 );
|
||||
STEP( 1, 1 ); STEP( 1, 2 ); STEP( 1, 3 ); STEP( 1, 4 );
|
||||
STEP( 1, 5 ); STEP( 1, 6 ); STEP( 1, 7 ); STEP( 1, 8 );
|
||||
STEP( 1, 9 ); STEP( 1, 10); STEP( 1, 11); STEP( 1, 12);
|
||||
L_result <<= 1;
|
||||
if (L_result > EM) {
|
||||
Mc = 1;
|
||||
EM = L_result;
|
||||
}
|
||||
|
||||
/* i = 2 */
|
||||
|
||||
L_result = 0;
|
||||
STEP( 2, 0 );
|
||||
STEP( 2, 1 ); STEP( 2, 2 ); STEP( 2, 3 ); STEP( 2, 4 );
|
||||
STEP( 2, 5 ); STEP( 2, 6 ); STEP( 2, 7 ); STEP( 2, 8 );
|
||||
STEP( 2, 9 ); STEP( 2, 10); STEP( 2, 11); STEP( 2, 12);
|
||||
L_result <<= 1;
|
||||
if (L_result > EM) {
|
||||
Mc = 2;
|
||||
EM = L_result;
|
||||
}
|
||||
|
||||
/* i = 3 */
|
||||
|
||||
L_result = L_common_0_3;
|
||||
STEP( 3, 12 );
|
||||
L_result <<= 1;
|
||||
if (L_result > EM) {
|
||||
Mc = 3;
|
||||
EM = L_result;
|
||||
}
|
||||
|
||||
/**/
|
||||
|
||||
/* Down-sampling by a factor 3 to get the selected xM[0..12]
|
||||
* RPE sequence.
|
||||
*/
|
||||
for (i = 0; i <= 12; i ++) xM[i] = x[Mc + 3*i];
|
||||
*Mc_out = Mc;
|
||||
}
|
||||
|
||||
/* 4.12.15 */
|
||||
|
||||
static void APCM_quantization_xmaxc_to_exp_mant P3((xmaxc,exp_out,mant_out),
|
||||
word xmaxc, /* IN */
|
||||
word * exp_out, /* OUT */
|
||||
word * mant_out ) /* OUT */
|
||||
{
|
||||
word exp, mant;
|
||||
|
||||
/* Compute exponent and mantissa of the decoded version of xmaxc
|
||||
*/
|
||||
|
||||
exp = 0;
|
||||
if (xmaxc > 15) exp = SASR(xmaxc, 3) - 1;
|
||||
mant = xmaxc - (exp << 3);
|
||||
|
||||
if (mant == 0) {
|
||||
exp = -4;
|
||||
mant = 7;
|
||||
}
|
||||
else {
|
||||
while (mant <= 7) {
|
||||
mant = mant << 1 | 1;
|
||||
exp--;
|
||||
}
|
||||
mant -= 8;
|
||||
}
|
||||
|
||||
assert( exp >= -4 && exp <= 6 );
|
||||
assert( mant >= 0 && mant <= 7 );
|
||||
|
||||
*exp_out = exp;
|
||||
*mant_out = mant;
|
||||
}
|
||||
|
||||
static void APCM_quantization P5((xM,xMc,mant_out,exp_out,xmaxc_out),
|
||||
word * xM, /* [0..12] IN */
|
||||
|
||||
word * xMc, /* [0..12] OUT */
|
||||
word * mant_out, /* OUT */
|
||||
word * exp_out, /* OUT */
|
||||
word * xmaxc_out /* OUT */
|
||||
)
|
||||
{
|
||||
int i, itest;
|
||||
|
||||
word xmax, xmaxc, temp, temp1, temp2;
|
||||
word exp, mant;
|
||||
|
||||
|
||||
/* Find the maximum absolute value xmax of xM[0..12].
|
||||
*/
|
||||
|
||||
xmax = 0;
|
||||
for (i = 0; i <= 12; i++) {
|
||||
temp = xM[i];
|
||||
temp = GSM_ABS(temp);
|
||||
if (temp > xmax) xmax = temp;
|
||||
}
|
||||
|
||||
/* Qantizing and coding of xmax to get xmaxc.
|
||||
*/
|
||||
|
||||
exp = 0;
|
||||
temp = SASR( xmax, 9 );
|
||||
itest = 0;
|
||||
|
||||
for (i = 0; i <= 5; i++) {
|
||||
|
||||
itest |= (temp <= 0);
|
||||
temp = SASR( temp, 1 );
|
||||
|
||||
assert(exp <= 5);
|
||||
if (itest == 0) exp++; /* exp = add (exp, 1) */
|
||||
}
|
||||
|
||||
assert(exp <= 6 && exp >= 0);
|
||||
temp = exp + 5;
|
||||
|
||||
assert(temp <= 11 && temp >= 0);
|
||||
xmaxc = gsm_add( SASR(xmax, temp), exp << 3 );
|
||||
|
||||
/* Quantizing and coding of the xM[0..12] RPE sequence
|
||||
* to get the xMc[0..12]
|
||||
*/
|
||||
|
||||
APCM_quantization_xmaxc_to_exp_mant( xmaxc, &exp, &mant );
|
||||
|
||||
/* This computation uses the fact that the decoded version of xmaxc
|
||||
* can be calculated by using the exponent and the mantissa part of
|
||||
* xmaxc (logarithmic table).
|
||||
* So, this method avoids any division and uses only a scaling
|
||||
* of the RPE samples by a function of the exponent. A direct
|
||||
* multiplication by the inverse of the mantissa (NRFAC[0..7]
|
||||
* found in table 4.5) gives the 3 bit coded version xMc[0..12]
|
||||
* of the RPE samples.
|
||||
*/
|
||||
|
||||
|
||||
/* Direct computation of xMc[0..12] using table 4.5
|
||||
*/
|
||||
|
||||
assert( exp <= 4096 && exp >= -4096);
|
||||
assert( mant >= 0 && mant <= 7 );
|
||||
|
||||
temp1 = 6 - exp; /* normalization by the exponent */
|
||||
temp2 = gsm_NRFAC[ mant ]; /* inverse mantissa */
|
||||
|
||||
for (i = 0; i <= 12; i++) {
|
||||
|
||||
assert(temp1 >= 0 && temp1 < 16);
|
||||
|
||||
temp = xM[i] << temp1;
|
||||
temp = GSM_MULT( temp, temp2 );
|
||||
temp = SASR(temp, 12);
|
||||
xMc[i] = temp + 4; /* see note below */
|
||||
}
|
||||
|
||||
/* NOTE: This equation is used to make all the xMc[i] positive.
|
||||
*/
|
||||
|
||||
*mant_out = mant;
|
||||
*exp_out = exp;
|
||||
*xmaxc_out = xmaxc;
|
||||
}
|
||||
|
||||
/* 4.2.16 */
|
||||
|
||||
static void APCM_inverse_quantization P4((xMc,mant,exp,xMp),
|
||||
register word * xMc, /* [0..12] IN */
|
||||
word mant,
|
||||
word exp,
|
||||
register word * xMp) /* [0..12] OUT */
|
||||
/*
|
||||
* This part is for decoding the RPE sequence of coded xMc[0..12]
|
||||
* samples to obtain the xMp[0..12] array. Table 4.6 is used to get
|
||||
* the mantissa of xmaxc (FAC[0..7]).
|
||||
*/
|
||||
{
|
||||
int i;
|
||||
word temp, temp1, temp2, temp3;
|
||||
longword ltmp;
|
||||
|
||||
assert( mant >= 0 && mant <= 7 );
|
||||
|
||||
temp1 = gsm_FAC[ mant ]; /* see 4.2-15 for mant */
|
||||
temp2 = gsm_sub( 6, exp ); /* see 4.2-15 for exp */
|
||||
temp3 = gsm_asl( 1, gsm_sub( temp2, 1 ));
|
||||
|
||||
for (i = 13; i--;) {
|
||||
|
||||
assert( *xMc <= 7 && *xMc >= 0 ); /* 3 bit unsigned */
|
||||
|
||||
/* temp = gsm_sub( *xMc++ << 1, 7 ); */
|
||||
temp = (*xMc++ << 1) - 7; /* restore sign */
|
||||
assert( temp <= 7 && temp >= -7 ); /* 4 bit signed */
|
||||
|
||||
temp <<= 12; /* 16 bit signed */
|
||||
temp = GSM_MULT_R( temp1, temp );
|
||||
temp = GSM_ADD( temp, temp3 );
|
||||
*xMp++ = gsm_asr( temp, temp2 );
|
||||
}
|
||||
}
|
||||
|
||||
/* 4.2.17 */
|
||||
|
||||
static void RPE_grid_positioning P3((Mc,xMp,ep),
|
||||
word Mc, /* grid position IN */
|
||||
register word * xMp, /* [0..12] IN */
|
||||
register word * ep /* [0..39] OUT */
|
||||
)
|
||||
/*
|
||||
* This procedure computes the reconstructed long term residual signal
|
||||
* ep[0..39] for the LTP analysis filter. The inputs are the Mc
|
||||
* which is the grid position selection and the xMp[0..12] decoded
|
||||
* RPE samples which are upsampled by a factor of 3 by inserting zero
|
||||
* values.
|
||||
*/
|
||||
{
|
||||
int i = 13;
|
||||
|
||||
assert(0 <= Mc && Mc <= 3);
|
||||
|
||||
switch (Mc) {
|
||||
case 3: *ep++ = 0;
|
||||
case 2: do {
|
||||
*ep++ = 0;
|
||||
case 1: *ep++ = 0;
|
||||
case 0: *ep++ = *xMp++;
|
||||
} while (--i);
|
||||
}
|
||||
while (++Mc < 4) *ep++ = 0;
|
||||
|
||||
/*
|
||||
|
||||
int i, k;
|
||||
for (k = 0; k <= 39; k++) ep[k] = 0;
|
||||
for (i = 0; i <= 12; i++) {
|
||||
ep[ Mc + (3*i) ] = xMp[i];
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
/* 4.2.18 */
|
||||
|
||||
/* This procedure adds the reconstructed long term residual signal
|
||||
* ep[0..39] to the estimated signal dpp[0..39] from the long term
|
||||
* analysis filter to compute the reconstructed short term residual
|
||||
* signal dp[-40..-1]; also the reconstructed short term residual
|
||||
* array dp[-120..-41] is updated.
|
||||
*/
|
||||
|
||||
#if 0 /* Has been inlined in code.c */
|
||||
void Gsm_Update_of_reconstructed_short_time_residual_signal P3((dpp, ep, dp),
|
||||
word * dpp, /* [0...39] IN */
|
||||
word * ep, /* [0...39] IN */
|
||||
word * dp) /* [-120...-1] IN/OUT */
|
||||
{
|
||||
int k;
|
||||
|
||||
for (k = 0; k <= 79; k++)
|
||||
dp[ -120 + k ] = dp[ -80 + k ];
|
||||
|
||||
for (k = 0; k <= 39; k++)
|
||||
dp[ -40 + k ] = gsm_add( ep[k], dpp[k] );
|
||||
}
|
||||
#endif /* Has been inlined in code.c */
|
||||
|
||||
void Gsm_RPE_Encoding P5((S,e,xmaxc,Mc,xMc),
|
||||
|
||||
struct gsm_state * S,
|
||||
|
||||
word * e, /* -5..-1][0..39][40..44 IN/OUT */
|
||||
word * xmaxc, /* OUT */
|
||||
word * Mc, /* OUT */
|
||||
word * xMc) /* [0..12] OUT */
|
||||
{
|
||||
word x[40];
|
||||
word xM[13], xMp[13];
|
||||
word mant, exp;
|
||||
|
||||
Weighting_filter(e, x);
|
||||
RPE_grid_selection(x, xM, Mc);
|
||||
|
||||
APCM_quantization( xM, xMc, &mant, &exp, xmaxc);
|
||||
APCM_inverse_quantization( xMc, mant, exp, xMp);
|
||||
|
||||
RPE_grid_positioning( *Mc, xMp, e );
|
||||
|
||||
}
|
||||
|
||||
void Gsm_RPE_Decoding P5((S, xmaxcr, Mcr, xMcr, erp),
|
||||
struct gsm_state * S,
|
||||
|
||||
word xmaxcr,
|
||||
word Mcr,
|
||||
word * xMcr, /* [0..12], 3 bits IN */
|
||||
word * erp /* [0..39] OUT */
|
||||
)
|
||||
{
|
||||
word exp, mant;
|
||||
word xMp[ 13 ];
|
||||
|
||||
APCM_quantization_xmaxc_to_exp_mant( xmaxcr, &exp, &mant );
|
||||
APCM_inverse_quantization( xMcr, mant, exp, xMp );
|
||||
RPE_grid_positioning( Mcr, xMp, erp );
|
||||
|
||||
}
|
452
utils/iaxclient/lib/gsm/src/short_term.c
Normal file
452
utils/iaxclient/lib/gsm/src/short_term.c
Normal file
|
@ -0,0 +1,452 @@
|
|||
/*
|
||||
* Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
|
||||
* Universitaet Berlin. See the accompanying file "COPYRIGHT" for
|
||||
* details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Header$ */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "private.h"
|
||||
|
||||
#include "gsm.h"
|
||||
#include "proto.h"
|
||||
#ifdef K6OPT
|
||||
#include "k6opt.h"
|
||||
|
||||
#define Short_term_analysis_filtering Short_term_analysis_filteringx
|
||||
|
||||
#endif
|
||||
/*
|
||||
* SHORT TERM ANALYSIS FILTERING SECTION
|
||||
*/
|
||||
|
||||
/* 4.2.8 */
|
||||
|
||||
static void Decoding_of_the_coded_Log_Area_Ratios P2((LARc,LARpp),
|
||||
word * LARc, /* coded log area ratio [0..7] IN */
|
||||
word * LARpp) /* out: decoded .. */
|
||||
{
|
||||
register word temp1 /* , temp2 */;
|
||||
register long ltmp; /* for GSM_ADD */
|
||||
|
||||
/* This procedure requires for efficient implementation
|
||||
* two tables.
|
||||
*
|
||||
* INVA[1..8] = integer( (32768 * 8) / real_A[1..8])
|
||||
* MIC[1..8] = minimum value of the LARc[1..8]
|
||||
*/
|
||||
|
||||
/* Compute the LARpp[1..8]
|
||||
*/
|
||||
|
||||
/* for (i = 1; i <= 8; i++, B++, MIC++, INVA++, LARc++, LARpp++) {
|
||||
*
|
||||
* temp1 = GSM_ADD( *LARc, *MIC ) << 10;
|
||||
* temp2 = *B << 1;
|
||||
* temp1 = GSM_SUB( temp1, temp2 );
|
||||
*
|
||||
* assert(*INVA != MIN_WORD);
|
||||
*
|
||||
* temp1 = GSM_MULT_R( *INVA, temp1 );
|
||||
* *LARpp = GSM_ADD( temp1, temp1 );
|
||||
* }
|
||||
*/
|
||||
|
||||
#undef STEP
|
||||
#define STEP( B, MIC, INVA ) \
|
||||
temp1 = (word) GSM_ADD( *LARc++, MIC ) << 10; \
|
||||
temp1 = (word) GSM_SUB( temp1, B << 1 ); \
|
||||
temp1 = (word) GSM_MULT_R( INVA, temp1 ); \
|
||||
*LARpp++ = (word) GSM_ADD( temp1, temp1 );
|
||||
|
||||
STEP( 0, -32, 13107 );
|
||||
STEP( 0, -32, 13107 );
|
||||
STEP( 2048, -16, 13107 );
|
||||
STEP( -2560, -16, 13107 );
|
||||
|
||||
STEP( 94, -8, 19223 );
|
||||
STEP( -1792, -8, 17476 );
|
||||
STEP( -341, -4, 31454 );
|
||||
STEP( -1144, -4, 29708 );
|
||||
|
||||
/* NOTE: the addition of *MIC is used to restore
|
||||
* the sign of *LARc.
|
||||
*/
|
||||
}
|
||||
|
||||
/* 4.2.9 */
|
||||
/* Computation of the quantized reflection coefficients
|
||||
*/
|
||||
|
||||
/* 4.2.9.1 Interpolation of the LARpp[1..8] to get the LARp[1..8]
|
||||
*/
|
||||
|
||||
/*
|
||||
* Within each frame of 160 analyzed speech samples the short term
|
||||
* analysis and synthesis filters operate with four different sets of
|
||||
* coefficients, derived from the previous set of decoded LARs(LARpp(j-1))
|
||||
* and the actual set of decoded LARs (LARpp(j))
|
||||
*
|
||||
* (Initial value: LARpp(j-1)[1..8] = 0.)
|
||||
*/
|
||||
|
||||
static void Coefficients_0_12 P3((LARpp_j_1, LARpp_j, LARp),
|
||||
register word * LARpp_j_1,
|
||||
register word * LARpp_j,
|
||||
register word * LARp)
|
||||
{
|
||||
register int i;
|
||||
register longword ltmp;
|
||||
|
||||
for (i = 1; i <= 8; i++, LARp++, LARpp_j_1++, LARpp_j++) {
|
||||
*LARp = GSM_ADD( SASR( *LARpp_j_1, 2 ), SASR( *LARpp_j, 2 ));
|
||||
*LARp = GSM_ADD( *LARp, SASR( *LARpp_j_1, 1));
|
||||
}
|
||||
}
|
||||
|
||||
static void Coefficients_13_26 P3((LARpp_j_1, LARpp_j, LARp),
|
||||
register word * LARpp_j_1,
|
||||
register word * LARpp_j,
|
||||
register word * LARp)
|
||||
{
|
||||
register int i;
|
||||
register longword ltmp;
|
||||
for (i = 1; i <= 8; i++, LARpp_j_1++, LARpp_j++, LARp++) {
|
||||
*LARp = GSM_ADD( SASR( *LARpp_j_1, 1), SASR( *LARpp_j, 1 ));
|
||||
}
|
||||
}
|
||||
|
||||
static void Coefficients_27_39 P3((LARpp_j_1, LARpp_j, LARp),
|
||||
register word * LARpp_j_1,
|
||||
register word * LARpp_j,
|
||||
register word * LARp)
|
||||
{
|
||||
register int i;
|
||||
register longword ltmp;
|
||||
|
||||
for (i = 1; i <= 8; i++, LARpp_j_1++, LARpp_j++, LARp++) {
|
||||
*LARp = GSM_ADD( SASR( *LARpp_j_1, 2 ), SASR( *LARpp_j, 2 ));
|
||||
*LARp = GSM_ADD( *LARp, SASR( *LARpp_j, 1 ));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void Coefficients_40_159 P2((LARpp_j, LARp),
|
||||
register word * LARpp_j,
|
||||
register word * LARp)
|
||||
{
|
||||
register int i;
|
||||
|
||||
for (i = 1; i <= 8; i++, LARp++, LARpp_j++)
|
||||
*LARp = *LARpp_j;
|
||||
}
|
||||
|
||||
/* 4.2.9.2 */
|
||||
|
||||
static void LARp_to_rp P1((LARp),
|
||||
register word * LARp) /* [0..7] IN/OUT */
|
||||
/*
|
||||
* The input of this procedure is the interpolated LARp[0..7] array.
|
||||
* The reflection coefficients, rp[i], are used in the analysis
|
||||
* filter and in the synthesis filter.
|
||||
*/
|
||||
{
|
||||
register int i;
|
||||
register word temp;
|
||||
register longword ltmp;
|
||||
|
||||
for (i = 1; i <= 8; i++, LARp++) {
|
||||
|
||||
/* temp = GSM_ABS( *LARp );
|
||||
*
|
||||
* if (temp < 11059) temp <<= 1;
|
||||
* else if (temp < 20070) temp += 11059;
|
||||
* else temp = GSM_ADD( temp >> 2, 26112 );
|
||||
*
|
||||
* *LARp = *LARp < 0 ? -temp : temp;
|
||||
*/
|
||||
|
||||
if (*LARp < 0) {
|
||||
temp = *LARp == MIN_WORD ? MAX_WORD : -(*LARp);
|
||||
*LARp = - ((temp < 11059) ? temp << 1
|
||||
: ((temp < 20070) ? temp + 11059
|
||||
: GSM_ADD( temp >> 2, 26112 )));
|
||||
} else {
|
||||
temp = *LARp;
|
||||
*LARp = (temp < 11059) ? temp << 1
|
||||
: ((temp < 20070) ? temp + 11059
|
||||
: GSM_ADD( temp >> 2, 26112 ));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* 4.2.10 */
|
||||
#ifndef Short_term_analysis_filtering
|
||||
|
||||
/* SJB Remark:
|
||||
* I tried 2 MMX versions of this function, neither is significantly
|
||||
* faster than the C version which follows. MMX might be useful if
|
||||
* one were processing 2 input streams in parallel.
|
||||
*/
|
||||
static void Short_term_analysis_filtering P4((u0,rp0,k_n,s),
|
||||
register word * u0,
|
||||
register word * rp0, /* [0..7] IN */
|
||||
register int k_n, /* k_end - k_start */
|
||||
register word * s /* [0..n-1] IN/OUT */
|
||||
)
|
||||
/*
|
||||
* This procedure computes the short term residual signal d[..] to be fed
|
||||
* to the RPE-LTP loop from the s[..] signal and from the local rp[..]
|
||||
* array (quantized reflection coefficients). As the call of this
|
||||
* procedure can be done in many ways (see the interpolation of the LAR
|
||||
* coefficient), it is assumed that the computation begins with index
|
||||
* k_start (for arrays d[..] and s[..]) and stops with index k_end
|
||||
* (k_start and k_end are defined in 4.2.9.1). This procedure also
|
||||
* needs to keep the array u0[0..7] in memory for each call.
|
||||
*/
|
||||
{
|
||||
register word * u_top = u0 + 8;
|
||||
register word * s_top = s + k_n;
|
||||
|
||||
while (s < s_top) {
|
||||
register word *u, *rp ;
|
||||
register longword di, u_out;
|
||||
di = u_out = *s;
|
||||
for (rp=rp0, u=u0; u<u_top;) {
|
||||
register longword ui, rpi;
|
||||
ui = *u;
|
||||
*u++ = (word) u_out;
|
||||
rpi = *rp++;
|
||||
u_out = ui + (((rpi*di)+0x4000)>>15);
|
||||
di = di + (((rpi*ui)+0x4000)>>15);
|
||||
/* make the common case fastest: */
|
||||
if ((u_out == (word)u_out) && (di == (word)di)) continue;
|
||||
/* otherwise do slower fixup (saturation) */
|
||||
if (u_out>MAX_WORD) u_out=MAX_WORD;
|
||||
else if (u_out<MIN_WORD) u_out=MIN_WORD;
|
||||
if (di>MAX_WORD) di=MAX_WORD;
|
||||
else if (di<MIN_WORD) di=MIN_WORD;
|
||||
}
|
||||
*s++ = (word) di;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(USE_FLOAT_MUL) && defined(FAST)
|
||||
|
||||
static void Fast_Short_term_analysis_filtering P4((u,rp,k_n,s),
|
||||
register word * u;
|
||||
register word * rp, /* [0..7] IN */
|
||||
register int k_n, /* k_end - k_start */
|
||||
register word * s /* [0..n-1] IN/OUT */
|
||||
)
|
||||
{
|
||||
register int i;
|
||||
|
||||
float uf[8],
|
||||
rpf[8];
|
||||
|
||||
register float scalef = 3.0517578125e-5;
|
||||
register float sav, di, temp;
|
||||
|
||||
for (i = 0; i < 8; ++i) {
|
||||
uf[i] = u[i];
|
||||
rpf[i] = rp[i] * scalef;
|
||||
}
|
||||
for (; k_n--; s++) {
|
||||
sav = di = *s;
|
||||
for (i = 0; i < 8; ++i) {
|
||||
register float rpfi = rpf[i];
|
||||
register float ufi = uf[i];
|
||||
|
||||
uf[i] = sav;
|
||||
temp = rpfi * di + ufi;
|
||||
di += rpfi * ufi;
|
||||
sav = temp;
|
||||
}
|
||||
*s = di;
|
||||
}
|
||||
for (i = 0; i < 8; ++i) u[i] = uf[i];
|
||||
}
|
||||
#endif /* ! (defined (USE_FLOAT_MUL) && defined (FAST)) */
|
||||
|
||||
/*
|
||||
* SJB Remark: modified Short_term_synthesis_filtering() below
|
||||
* for significant (abt 35%) speedup of decompression.
|
||||
* (gcc-2.95, k6 cpu)
|
||||
* Please don't change this without benchmarking decompression
|
||||
* to see that you haven't harmed speed.
|
||||
* This function burns most of CPU time for untoasting.
|
||||
* Unfortunately, didn't see any good way to benefit from mmx.
|
||||
*/
|
||||
static void Short_term_synthesis_filtering P5((S,rrp,k,wt,sr),
|
||||
struct gsm_state * S,
|
||||
register word * rrp, /* [0..7] IN */
|
||||
register int k, /* k_end - k_start */
|
||||
register word * wt, /* [0..k-1] IN */
|
||||
register word * sr /* [0..k-1] OUT */
|
||||
)
|
||||
{
|
||||
register word * v = S->v;
|
||||
register int i;
|
||||
register longword sri;
|
||||
|
||||
while (k--) {
|
||||
sri = *wt++;
|
||||
for (i = 8; i--;) {
|
||||
register longword tmp1, tmp2;
|
||||
|
||||
/* sri = GSM_SUB( sri, gsm_mult_r( rrp[i], v[i] ) );
|
||||
*/
|
||||
tmp1 = rrp[i];
|
||||
tmp2 = v[i];
|
||||
|
||||
tmp2 = (( tmp1 * tmp2 + 16384) >> 15) ;
|
||||
/* saturation done below */
|
||||
sri -= tmp2;
|
||||
if (sri != (word)sri) {
|
||||
sri = (sri<0)? MIN_WORD:MAX_WORD;
|
||||
}
|
||||
/* v[i+1] = GSM_ADD( v[i], gsm_mult_r( rrp[i], sri ) );
|
||||
*/
|
||||
|
||||
tmp1 = (( tmp1 * sri + 16384) >> 15) ;
|
||||
/* saturation done below */
|
||||
tmp1 += v[i];
|
||||
if (tmp1 != (word)tmp1) {
|
||||
tmp1 = (tmp1<0)? MIN_WORD:MAX_WORD;
|
||||
}
|
||||
v[i+1] = (word) tmp1;
|
||||
}
|
||||
*sr++ = v[0] = (word) sri;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if defined(FAST) && defined(USE_FLOAT_MUL)
|
||||
|
||||
static void Fast_Short_term_synthesis_filtering P5((S,rrp,k,wt,sr),
|
||||
struct gsm_state * S,
|
||||
register word * rrp, /* [0..7] IN */
|
||||
register int k, /* k_end - k_start */
|
||||
register word * wt, /* [0..k-1] IN */
|
||||
register word * sr /* [0..k-1] OUT */
|
||||
)
|
||||
{
|
||||
register word * v = S->v;
|
||||
register int i;
|
||||
|
||||
float va[9], rrpa[8];
|
||||
register float scalef = 3.0517578125e-5, temp;
|
||||
|
||||
for (i = 0; i < 8; ++i) {
|
||||
va[i] = v[i];
|
||||
rrpa[i] = (float)rrp[i] * scalef;
|
||||
}
|
||||
while (k--) {
|
||||
register float sri = *wt++;
|
||||
for (i = 8; i--;) {
|
||||
sri -= rrpa[i] * va[i];
|
||||
if (sri < -32768.) sri = -32768.;
|
||||
else if (sri > 32767.) sri = 32767.;
|
||||
|
||||
temp = va[i] + rrpa[i] * sri;
|
||||
if (temp < -32768.) temp = -32768.;
|
||||
else if (temp > 32767.) temp = 32767.;
|
||||
va[i+1] = temp;
|
||||
}
|
||||
*sr++ = va[0] = sri;
|
||||
}
|
||||
for (i = 0; i < 9; ++i) v[i] = va[i];
|
||||
}
|
||||
|
||||
#endif /* defined(FAST) && defined(USE_FLOAT_MUL) */
|
||||
|
||||
void Gsm_Short_Term_Analysis_Filter P3((S,LARc,s),
|
||||
|
||||
struct gsm_state * S,
|
||||
|
||||
word * LARc, /* coded log area ratio [0..7] IN */
|
||||
word * s /* signal [0..159] IN/OUT */
|
||||
)
|
||||
{
|
||||
word * LARpp_j = S->LARpp[ S->j ];
|
||||
word * LARpp_j_1 = S->LARpp[ S->j ^= 1 ];
|
||||
|
||||
word LARp[8];
|
||||
#undef FILTER
|
||||
#if defined(FAST) && defined(USE_FLOAT_MUL)
|
||||
# define FILTER (* (S->fast \
|
||||
? Fast_Short_term_analysis_filtering \
|
||||
: Short_term_analysis_filtering ))
|
||||
|
||||
#else
|
||||
# define FILTER Short_term_analysis_filtering
|
||||
#endif
|
||||
|
||||
Decoding_of_the_coded_Log_Area_Ratios( LARc, LARpp_j );
|
||||
|
||||
Coefficients_0_12( LARpp_j_1, LARpp_j, LARp );
|
||||
LARp_to_rp( LARp );
|
||||
FILTER( S->u, LARp, 13, s);
|
||||
|
||||
Coefficients_13_26( LARpp_j_1, LARpp_j, LARp);
|
||||
LARp_to_rp( LARp );
|
||||
FILTER( S->u, LARp, 14, s + 13);
|
||||
|
||||
Coefficients_27_39( LARpp_j_1, LARpp_j, LARp);
|
||||
LARp_to_rp( LARp );
|
||||
FILTER( S->u, LARp, 13, s + 27);
|
||||
|
||||
Coefficients_40_159( LARpp_j, LARp);
|
||||
LARp_to_rp( LARp );
|
||||
FILTER( S->u, LARp, 120, s + 40);
|
||||
|
||||
}
|
||||
|
||||
void Gsm_Short_Term_Synthesis_Filter P4((S, LARcr, wt, s),
|
||||
struct gsm_state * S,
|
||||
|
||||
word * LARcr, /* received log area ratios [0..7] IN */
|
||||
word * wt, /* received d [0..159] IN */
|
||||
|
||||
word * s /* signal s [0..159] OUT */
|
||||
)
|
||||
{
|
||||
word * LARpp_j = S->LARpp[ S->j ];
|
||||
word * LARpp_j_1 = S->LARpp[ S->j ^=1 ];
|
||||
|
||||
word LARp[8];
|
||||
|
||||
#undef FILTER
|
||||
#if defined(FAST) && defined(USE_FLOAT_MUL)
|
||||
|
||||
# define FILTER (* (S->fast \
|
||||
? Fast_Short_term_synthesis_filtering \
|
||||
: Short_term_synthesis_filtering ))
|
||||
#else
|
||||
# define FILTER Short_term_synthesis_filtering
|
||||
#endif
|
||||
|
||||
Decoding_of_the_coded_Log_Area_Ratios( LARcr, LARpp_j );
|
||||
|
||||
Coefficients_0_12( LARpp_j_1, LARpp_j, LARp );
|
||||
LARp_to_rp( LARp );
|
||||
FILTER( S, LARp, 13, wt, s );
|
||||
|
||||
Coefficients_13_26( LARpp_j_1, LARpp_j, LARp);
|
||||
LARp_to_rp( LARp );
|
||||
FILTER( S, LARp, 14, wt + 13, s + 13 );
|
||||
|
||||
Coefficients_27_39( LARpp_j_1, LARpp_j, LARp);
|
||||
LARp_to_rp( LARp );
|
||||
FILTER( S, LARp, 13, wt + 27, s + 27 );
|
||||
|
||||
Coefficients_40_159( LARpp_j, LARp );
|
||||
LARp_to_rp( LARp );
|
||||
FILTER(S, LARp, 120, wt + 40, s + 40);
|
||||
}
|
63
utils/iaxclient/lib/gsm/src/table.c
Normal file
63
utils/iaxclient/lib/gsm/src/table.c
Normal file
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
|
||||
* Universitaet Berlin. See the accompanying file "COPYRIGHT" for
|
||||
* details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Header$ */
|
||||
|
||||
/* Most of these tables are inlined at their point of use.
|
||||
*/
|
||||
|
||||
/* 4.4 TABLES USED IN THE FIXED POINT IMPLEMENTATION OF THE RPE-LTP
|
||||
* CODER AND DECODER
|
||||
*
|
||||
* (Most of them inlined, so watch out.)
|
||||
*/
|
||||
|
||||
#define GSM_TABLE_C
|
||||
#include "private.h"
|
||||
#include "gsm.h"
|
||||
|
||||
/* Table 4.1 Quantization of the Log.-Area Ratios
|
||||
*/
|
||||
/* i 1 2 3 4 5 6 7 8 */
|
||||
word gsm_A[8] = {20480, 20480, 20480, 20480, 13964, 15360, 8534, 9036};
|
||||
word gsm_B[8] = { 0, 0, 2048, -2560, 94, -1792, -341, -1144};
|
||||
word gsm_MIC[8] = { -32, -32, -16, -16, -8, -8, -4, -4 };
|
||||
word gsm_MAC[8] = { 31, 31, 15, 15, 7, 7, 3, 3 };
|
||||
|
||||
|
||||
/* Table 4.2 Tabulation of 1/A[1..8]
|
||||
*/
|
||||
word gsm_INVA[8]={ 13107, 13107, 13107, 13107, 19223, 17476, 31454, 29708 };
|
||||
|
||||
|
||||
/* Table 4.3a Decision level of the LTP gain quantizer
|
||||
*/
|
||||
/* bc 0 1 2 3 */
|
||||
word gsm_DLB[4] = { 6554, 16384, 26214, 32767 };
|
||||
|
||||
|
||||
/* Table 4.3b Quantization levels of the LTP gain quantizer
|
||||
*/
|
||||
/* bc 0 1 2 3 */
|
||||
word gsm_QLB[4] = { 3277, 11469, 21299, 32767 };
|
||||
|
||||
|
||||
/* Table 4.4 Coefficients of the weighting filter
|
||||
*/
|
||||
/* i 0 1 2 3 4 5 6 7 8 9 10 */
|
||||
word gsm_H[11] = {-134, -374, 0, 2054, 5741, 8192, 5741, 2054, 0, -374, -134 };
|
||||
|
||||
|
||||
/* Table 4.5 Normalized inverse mantissa used to compute xM/xmax
|
||||
*/
|
||||
/* i 0 1 2 3 4 5 6 7 */
|
||||
word gsm_NRFAC[8] = { 29128, 26215, 23832, 21846, 20165, 18725, 17476, 16384 };
|
||||
|
||||
|
||||
/* Table 4.6 Normalized direct mantissa used to compute xM/xmax
|
||||
*/
|
||||
/* i 0 1 2 3 4 5 6 7 */
|
||||
word gsm_FAC[8] = { 18431, 20479, 22527, 24575, 26623, 28671, 30719, 32767 };
|
1379
utils/iaxclient/lib/iaxclient.h
Normal file
1379
utils/iaxclient/lib/iaxclient.h
Normal file
File diff suppressed because it is too large
Load diff
1982
utils/iaxclient/lib/iaxclient_lib.c
Normal file
1982
utils/iaxclient/lib/iaxclient_lib.c
Normal file
File diff suppressed because it is too large
Load diff
270
utils/iaxclient/lib/iaxclient_lib.h
Normal file
270
utils/iaxclient/lib/iaxclient_lib.h
Normal file
|
@ -0,0 +1,270 @@
|
|||
/*
|
||||
* iaxclient: a cross-platform IAX softphone library
|
||||
*
|
||||
* Copyrights:
|
||||
* Copyright (C) 2003-2006, Horizon Wimba, Inc.
|
||||
* Copyright (C) 2007, Wimba, Inc.
|
||||
*
|
||||
* Contributors:
|
||||
* Steve Kann <stevek@stevek.com>
|
||||
* Michael Van Donselaar <mvand@vandonselaar.org>
|
||||
* Shawn Lawrence <shawn.lawrence@terracecomm.com>
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU Lesser (Library) General Public License.
|
||||
*/
|
||||
#ifndef _iaxclient_lib_h
|
||||
#define _iaxclient_lib_h
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/* This is the internal include file for IAXCLIENT -- externally
|
||||
* accessible APIs should be declared in iaxclient.h */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#if defined(WIN32) || defined(_WIN32_WCE)
|
||||
#include "winpoop.h"
|
||||
#if !defined(_WIN32_WCE)
|
||||
#include <process.h>
|
||||
#endif
|
||||
#include <stddef.h>
|
||||
#include <time.h>
|
||||
|
||||
#else
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/time.h>
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
#ifdef USE_FFMPEG
|
||||
// To access to check_ff function
|
||||
#include "codec_ffmpeg.h"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include "spandsp/plc.h"
|
||||
|
||||
|
||||
|
||||
/* os-dependent macros, etc */
|
||||
#if defined(WIN32) || defined(_WIN32_WCE)
|
||||
#define THREAD HANDLE
|
||||
#define THREADID unsigned
|
||||
#define THREADCREATE(func, args, thread, id) \
|
||||
(thread = (HANDLE)_beginthreadex(NULL, 0, func, (PVOID)args, 0, &id))
|
||||
#define THREADCREATE_ERROR NULL
|
||||
#define THREADFUNCDECL(func) unsigned __stdcall func(PVOID args)
|
||||
#define THREADFUNCRET(r) int r = 0
|
||||
#define THREADJOIN(t)
|
||||
/* causes deadlock with wx GUI on MSW */
|
||||
/* #define THREADJOIN(t) WaitForSingleObject(t, INFINITE) */
|
||||
#ifndef _WIN32_WINNT
|
||||
extern WINBASEAPI BOOL WINAPI TryEnterCriticalSection( LPCRITICAL_SECTION lpCriticalSection );
|
||||
#endif
|
||||
#define MUTEX CRITICAL_SECTION
|
||||
#define MUTEXINIT(m) InitializeCriticalSection(m)
|
||||
#define MUTEXLOCK(m) EnterCriticalSection(m)
|
||||
#define MUTEXTRYLOCK(m) (!TryEnterCriticalSection(m))
|
||||
#define MUTEXUNLOCK(m) LeaveCriticalSection(m)
|
||||
#define MUTEXDESTROY(m) DeleteCriticalSection(m)
|
||||
|
||||
#else
|
||||
#define THREAD pthread_t
|
||||
#define THREADID unsigned /* unused for Posix Threads */
|
||||
#define THREADCREATE(func, args, thread, id) \
|
||||
pthread_create(&thread, NULL, func, args)
|
||||
#define THREADCREATE_ERROR -1
|
||||
#define THREADFUNCDECL(func) void * func(void *args)
|
||||
#define THREADFUNCRET(r) void * r = 0
|
||||
#define THREADJOIN(t) pthread_join(t, 0)
|
||||
#define MUTEX pthread_mutex_t
|
||||
#define MUTEXINIT(m) pthread_mutex_init(m, NULL) //TODO: check error
|
||||
#define MUTEXLOCK(m) pthread_mutex_lock(m)
|
||||
#define MUTEXTRYLOCK(m) pthread_mutex_trylock(m)
|
||||
#define MUTEXUNLOCK(m) pthread_mutex_unlock(m)
|
||||
#define MUTEXDESTROY(m) pthread_mutex_destroy(m)
|
||||
#endif
|
||||
|
||||
#ifdef MACOSX
|
||||
#include <mach/mach_init.h>
|
||||
#include <mach/thread_policy.h>
|
||||
#include <sched.h>
|
||||
#include <sys/sysctl.h>
|
||||
#endif
|
||||
|
||||
#define MAXARGS 10
|
||||
#define MAXARG 256
|
||||
#define MAX_SESSIONS 4
|
||||
#define OUT_INTERVAL 20
|
||||
|
||||
/* millisecond interval to time out calls */
|
||||
#define IAXC_CALL_TIMEOUT 30000
|
||||
|
||||
|
||||
void os_init(void);
|
||||
void iaxci_usermsg(int type, const char *fmt, ...);
|
||||
void iaxci_do_levels_callback(float input, float output);
|
||||
void iaxci_do_audio_callback(int callNo, unsigned int ts, int remote,
|
||||
int encoded, int format, int size, unsigned char *data);
|
||||
|
||||
#include "iaxclient.h"
|
||||
|
||||
struct iaxc_audio_driver {
|
||||
/* data */
|
||||
char *name; /* driver name */
|
||||
struct iaxc_audio_device *devices; /* list of devices */
|
||||
int nDevices; /* count of devices */
|
||||
void *priv; /* pointer to private data */
|
||||
|
||||
/* methods */
|
||||
int (*initialize)(struct iaxc_audio_driver *d, int sample_rate);
|
||||
int (*destroy)(struct iaxc_audio_driver *d); /* free resources */
|
||||
int (*select_devices)(struct iaxc_audio_driver *d, int input, int output, int ring);
|
||||
int (*selected_devices)(struct iaxc_audio_driver *d, int *input, int *output, int *ring);
|
||||
|
||||
/*
|
||||
* select_ring ?
|
||||
* set_latency
|
||||
*/
|
||||
|
||||
int (*start)(struct iaxc_audio_driver *d);
|
||||
int (*stop)(struct iaxc_audio_driver *d);
|
||||
int (*output)(struct iaxc_audio_driver *d, void *samples, int nSamples);
|
||||
int (*input)(struct iaxc_audio_driver *d, void *samples, int *nSamples);
|
||||
|
||||
/* levels */
|
||||
float (*input_level_get)(struct iaxc_audio_driver *d);
|
||||
float (*output_level_get)(struct iaxc_audio_driver *d);
|
||||
int (*input_level_set)(struct iaxc_audio_driver *d, float level);
|
||||
int (*output_level_set)(struct iaxc_audio_driver *d, float level);
|
||||
|
||||
/* sounds */
|
||||
int (*play_sound)(struct iaxc_sound *s, int ring);
|
||||
int (*stop_sound)(int id);
|
||||
|
||||
/* mic boost */
|
||||
int (*mic_boost_get)(struct iaxc_audio_driver *d ) ;
|
||||
int (*mic_boost_set)(struct iaxc_audio_driver *d, int enable);
|
||||
};
|
||||
|
||||
struct iaxc_audio_codec {
|
||||
char name[256];
|
||||
int format;
|
||||
int minimum_frame_size;
|
||||
void *encstate;
|
||||
void *decstate;
|
||||
int (*encode) ( struct iaxc_audio_codec *codec, int *inlen, short *in, int *outlen, unsigned char *out );
|
||||
int (*decode) ( struct iaxc_audio_codec *codec, int *inlen, unsigned char *in, int *outlen, short *out );
|
||||
void (*destroy) ( struct iaxc_audio_codec *codec);
|
||||
};
|
||||
|
||||
#define MAX_TRUNK_LEN (1<<16)
|
||||
#define MAX_NO_SLICES 32
|
||||
|
||||
struct slice_set_t
|
||||
{
|
||||
int num_slices;
|
||||
int key_frame;
|
||||
int size[MAX_NO_SLICES];
|
||||
char data[MAX_NO_SLICES][MAX_TRUNK_LEN];
|
||||
};
|
||||
|
||||
struct iaxc_video_codec {
|
||||
char name[256];
|
||||
int format;
|
||||
int width;
|
||||
int height;
|
||||
int framerate;
|
||||
int bitrate;
|
||||
int fragsize;
|
||||
int params_changed;
|
||||
void *encstate;
|
||||
void *decstate;
|
||||
struct iaxc_video_stats video_stats;
|
||||
int (*encode)(struct iaxc_video_codec * codec, int inlen,
|
||||
const char * in, struct slice_set_t * out);
|
||||
int (*decode)(struct iaxc_video_codec * codec, int inlen,
|
||||
const char * in, int * outlen, char * out);
|
||||
void (*destroy)(struct iaxc_video_codec * codec);
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct iaxc_call {
|
||||
/* to be replaced with codec-structures, with codec-private data */
|
||||
struct iaxc_audio_codec *encoder;
|
||||
struct iaxc_audio_codec *decoder;
|
||||
struct iaxc_video_codec *vencoder;
|
||||
struct iaxc_video_codec *vdecoder;
|
||||
int vformat;
|
||||
|
||||
/* the "state" of this call */
|
||||
int state;
|
||||
char remote[IAXC_EVENT_BUFSIZ];
|
||||
char remote_name[IAXC_EVENT_BUFSIZ];
|
||||
char local[IAXC_EVENT_BUFSIZ];
|
||||
char local_context[IAXC_EVENT_BUFSIZ];
|
||||
|
||||
/* Outbound CallerID */
|
||||
char callerid_name[IAXC_EVENT_BUFSIZ];
|
||||
char callerid_number[IAXC_EVENT_BUFSIZ];
|
||||
|
||||
/* reset whenever we receive packets from remote */
|
||||
struct timeval last_activity;
|
||||
struct timeval last_ping;
|
||||
|
||||
/* our negotiated format */
|
||||
int format;
|
||||
|
||||
/* we've sent a silent frame since the last audio frame */
|
||||
int tx_silent;
|
||||
|
||||
struct iax_session *session;
|
||||
};
|
||||
|
||||
#include "audio_encode.h"
|
||||
|
||||
#ifdef AUDIO_PA
|
||||
#include "audio_portaudio.h"
|
||||
#endif
|
||||
|
||||
#include "audio_file.h"
|
||||
|
||||
#ifdef AUDIO_OPENAL
|
||||
#include "audio_openal.h"
|
||||
#endif
|
||||
|
||||
extern int iaxci_audio_output_mode;
|
||||
|
||||
int iaxci_post_event_callback(iaxc_event e);
|
||||
|
||||
/* post an event to the application */
|
||||
void iaxci_post_event(iaxc_event e);
|
||||
|
||||
/* parameters for callback */
|
||||
extern void * post_event_handle;
|
||||
extern int post_event_id;
|
||||
|
||||
/* Priority boost support */
|
||||
extern int iaxci_prioboostbegin(void);
|
||||
extern int iaxci_prioboostend(void);
|
||||
|
||||
long iaxci_usecdiff(struct timeval *t0, struct timeval *t1);
|
||||
long iaxci_msecdiff(struct timeval *t0, struct timeval *t1);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
0
utils/iaxclient/lib/libiax2/AUTHORS
Normal file
0
utils/iaxclient/lib/libiax2/AUTHORS
Normal file
416
utils/iaxclient/lib/libiax2/COPYING
Normal file
416
utils/iaxclient/lib/libiax2/COPYING
Normal file
|
@ -0,0 +1,416 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
675 Mass Ave, Cambridge, MA 02139, USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Appendix: How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) 19yy <name of author>
|
||||
|
||||
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.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) 19yy name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
482
utils/iaxclient/lib/libiax2/COPYING.LIB
Normal file
482
utils/iaxclient/lib/libiax2/COPYING.LIB
Normal file
|
@ -0,0 +1,482 @@
|
|||
GNU LIBRARY GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the library GPL. It is
|
||||
numbered 2 because it goes with version 2 of the ordinary GPL.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Library General Public License, applies to some
|
||||
specially designated Free Software Foundation software, and to any
|
||||
other libraries whose authors decide to use it. You can use it for
|
||||
your libraries, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if
|
||||
you distribute copies of the library, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link a program with the library, you must provide
|
||||
complete object files to the recipients so that they can relink them
|
||||
with the library, after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
Our method of protecting your rights has two steps: (1) copyright
|
||||
the library, and (2) offer you this license which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
Also, for each distributor's protection, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
library. If the library is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original
|
||||
version, so that any problems introduced by others will not reflect on
|
||||
the original authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that companies distributing free
|
||||
software will individually obtain patent licenses, thus in effect
|
||||
transforming the program into proprietary software. To prevent this,
|
||||
we have made it clear that any patent must be licensed for everyone's
|
||||
free use or not licensed at all.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the ordinary
|
||||
GNU General Public License, which was designed for utility programs. This
|
||||
license, the GNU Library General Public License, applies to certain
|
||||
designated libraries. This license is quite different from the ordinary
|
||||
one; be sure to read it in full, and don't assume that anything in it is
|
||||
the same as in the ordinary license.
|
||||
|
||||
The reason we have a separate public license for some libraries is that
|
||||
they blur the distinction we usually make between modifying or adding to a
|
||||
program and simply using it. Linking a program with a library, without
|
||||
changing the library, is in some sense simply using the library, and is
|
||||
analogous to running a utility program or application program. However, in
|
||||
a textual and legal sense, the linked executable is a combined work, a
|
||||
derivative of the original library, and the ordinary General Public License
|
||||
treats it as such.
|
||||
|
||||
Because of this blurred distinction, using the ordinary General
|
||||
Public License for libraries did not effectively promote software
|
||||
sharing, because most developers did not use the libraries. We
|
||||
concluded that weaker conditions might promote sharing better.
|
||||
|
||||
However, unrestricted linking of non-free programs would deprive the
|
||||
users of those programs of all benefit from the free status of the
|
||||
libraries themselves. This Library General Public License is intended to
|
||||
permit developers of non-free programs to use free libraries, while
|
||||
preserving your freedom as a user of such programs to change the free
|
||||
libraries that are incorporated in them. (We have not seen how to achieve
|
||||
this as regards changes in header files, but we have achieved it as regards
|
||||
changes in the actual functions of the Library.) The hope is that this
|
||||
will lead to faster development of free libraries.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, while the latter only
|
||||
works together with the library.
|
||||
|
||||
Note that it is possible for a library to be covered by the ordinary
|
||||
General Public License rather than by this special one.
|
||||
|
||||
GNU LIBRARY GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library which
|
||||
contains a notice placed by the copyright holder or other authorized
|
||||
party saying it may be distributed under the terms of this Library
|
||||
General Public License (also called "this License"). Each licensee is
|
||||
addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, complete source code means
|
||||
all the source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control compilation
|
||||
and installation of the library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete source code as you receive it, in any medium, provided that
|
||||
you conspicuously and appropriately publish on each copy an
|
||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||
all the notices that refer to this License and to the absence of any
|
||||
warranty; and distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy,
|
||||
and you may at your option offer warranty protection in exchange for a
|
||||
fee.
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Library, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you accompany
|
||||
it with the complete corresponding machine-readable source code, which
|
||||
must be distributed under the terms of Sections 1 and 2 above on a
|
||||
medium customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also compile or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
c) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
d) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the source code distributed need not include anything that is normally
|
||||
distributed (in either source or binary form) with the major
|
||||
components (compiler, kernel, and so on) of the operating system on
|
||||
which the executable runs, unless that component itself accompanies
|
||||
the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library is void, and will automatically terminate your
|
||||
rights under this License. However, parties who have received copies,
|
||||
or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply,
|
||||
and the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library under this License may add
|
||||
an explicit geographical distribution limitation excluding those countries,
|
||||
so that distribution is permitted only in or among countries not thus
|
||||
excluded. In such case, this License incorporates the limitation as if
|
||||
written in the body of this License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Library General Public License from time to time.
|
||||
Such new versions will be similar in spirit to the present version,
|
||||
but may differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library
|
||||
specifies a version number of this License which applies to it and
|
||||
"any later version", you have the option of following the terms and
|
||||
conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
copyrighted by the Free Software Foundation, write to the Free
|
||||
Software Foundation; we sometimes make exceptions for this. Our
|
||||
decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
Appendix: How to Apply These Terms to Your New Libraries
|
||||
|
||||
If you develop a new library, and you want it to be of the greatest
|
||||
possible use to the public, we recommend making it free software that
|
||||
everyone can redistribute and change. You can do so by permitting
|
||||
redistribution under these terms (or, alternatively, under the terms of the
|
||||
ordinary General Public License).
|
||||
|
||||
To apply these terms, attach the following notices to the library. It is
|
||||
safest to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least the
|
||||
"copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the library's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
MA 02111-1307, USA
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1990
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
21
utils/iaxclient/lib/libiax2/ChangeLog
Normal file
21
utils/iaxclient/lib/libiax2/ChangeLog
Normal file
|
@ -0,0 +1,21 @@
|
|||
libiax
|
||||
======
|
||||
|
||||
version 0.2.3:
|
||||
* Allow password to be passed in connect
|
||||
|
||||
version 0.2.2 (Nov 13th, 2001):
|
||||
* HTML Unlink requests
|
||||
* HTML Reject link requests
|
||||
* Text frames
|
||||
|
||||
version 0.2.1 (Oct 20th, 2001):
|
||||
* More space for challenge in IAX
|
||||
* Fixed strncpy security bug
|
||||
* Accept larger packets
|
||||
* Handle out of order packets better
|
||||
* Implemented send_url
|
||||
* Added an iax-config script :-)
|
||||
|
||||
version 0.2.0 (Oct 10th, 2001):
|
||||
* Initial Public Release
|
236
utils/iaxclient/lib/libiax2/INSTALL
Normal file
236
utils/iaxclient/lib/libiax2/INSTALL
Normal file
|
@ -0,0 +1,236 @@
|
|||
Installation Instructions
|
||||
*************************
|
||||
|
||||
Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005 Free
|
||||
Software Foundation, Inc.
|
||||
|
||||
This file is free documentation; the Free Software Foundation gives
|
||||
unlimited permission to copy, distribute and modify it.
|
||||
|
||||
Basic Installation
|
||||
==================
|
||||
|
||||
These are generic installation instructions.
|
||||
|
||||
The `configure' shell script attempts to guess correct values for
|
||||
various system-dependent variables used during compilation. It uses
|
||||
those values to create a `Makefile' in each directory of the package.
|
||||
It may also create one or more `.h' files containing system-dependent
|
||||
definitions. Finally, it creates a shell script `config.status' that
|
||||
you can run in the future to recreate the current configuration, and a
|
||||
file `config.log' containing compiler output (useful mainly for
|
||||
debugging `configure').
|
||||
|
||||
It can also use an optional file (typically called `config.cache'
|
||||
and enabled with `--cache-file=config.cache' or simply `-C') that saves
|
||||
the results of its tests to speed up reconfiguring. (Caching is
|
||||
disabled by default to prevent problems with accidental use of stale
|
||||
cache files.)
|
||||
|
||||
If you need to do unusual things to compile the package, please try
|
||||
to figure out how `configure' could check whether to do them, and mail
|
||||
diffs or instructions to the address given in the `README' so they can
|
||||
be considered for the next release. If you are using the cache, and at
|
||||
some point `config.cache' contains results you don't want to keep, you
|
||||
may remove or edit it.
|
||||
|
||||
The file `configure.ac' (or `configure.in') is used to create
|
||||
`configure' by a program called `autoconf'. You only need
|
||||
`configure.ac' if you want to change it or regenerate `configure' using
|
||||
a newer version of `autoconf'.
|
||||
|
||||
The simplest way to compile this package is:
|
||||
|
||||
1. `cd' to the directory containing the package's source code and type
|
||||
`./configure' to configure the package for your system. If you're
|
||||
using `csh' on an old version of System V, you might need to type
|
||||
`sh ./configure' instead to prevent `csh' from trying to execute
|
||||
`configure' itself.
|
||||
|
||||
Running `configure' takes awhile. While running, it prints some
|
||||
messages telling which features it is checking for.
|
||||
|
||||
2. Type `make' to compile the package.
|
||||
|
||||
3. Optionally, type `make check' to run any self-tests that come with
|
||||
the package.
|
||||
|
||||
4. Type `make install' to install the programs and any data files and
|
||||
documentation.
|
||||
|
||||
5. You can remove the program binaries and object files from the
|
||||
source code directory by typing `make clean'. To also remove the
|
||||
files that `configure' created (so you can compile the package for
|
||||
a different kind of computer), type `make distclean'. There is
|
||||
also a `make maintainer-clean' target, but that is intended mainly
|
||||
for the package's developers. If you use it, you may have to get
|
||||
all sorts of other programs in order to regenerate files that came
|
||||
with the distribution.
|
||||
|
||||
Compilers and Options
|
||||
=====================
|
||||
|
||||
Some systems require unusual options for compilation or linking that the
|
||||
`configure' script does not know about. Run `./configure --help' for
|
||||
details on some of the pertinent environment variables.
|
||||
|
||||
You can give `configure' initial values for configuration parameters
|
||||
by setting variables in the command line or in the environment. Here
|
||||
is an example:
|
||||
|
||||
./configure CC=c89 CFLAGS=-O2 LIBS=-lposix
|
||||
|
||||
*Note Defining Variables::, for more details.
|
||||
|
||||
Compiling For Multiple Architectures
|
||||
====================================
|
||||
|
||||
You can compile the package for more than one kind of computer at the
|
||||
same time, by placing the object files for each architecture in their
|
||||
own directory. To do this, you must use a version of `make' that
|
||||
supports the `VPATH' variable, such as GNU `make'. `cd' to the
|
||||
directory where you want the object files and executables to go and run
|
||||
the `configure' script. `configure' automatically checks for the
|
||||
source code in the directory that `configure' is in and in `..'.
|
||||
|
||||
If you have to use a `make' that does not support the `VPATH'
|
||||
variable, you have to compile the package for one architecture at a
|
||||
time in the source code directory. After you have installed the
|
||||
package for one architecture, use `make distclean' before reconfiguring
|
||||
for another architecture.
|
||||
|
||||
Installation Names
|
||||
==================
|
||||
|
||||
By default, `make install' installs the package's commands under
|
||||
`/usr/local/bin', include files under `/usr/local/include', etc. You
|
||||
can specify an installation prefix other than `/usr/local' by giving
|
||||
`configure' the option `--prefix=PREFIX'.
|
||||
|
||||
You can specify separate installation prefixes for
|
||||
architecture-specific files and architecture-independent files. If you
|
||||
pass the option `--exec-prefix=PREFIX' to `configure', the package uses
|
||||
PREFIX as the prefix for installing programs and libraries.
|
||||
Documentation and other data files still use the regular prefix.
|
||||
|
||||
In addition, if you use an unusual directory layout you can give
|
||||
options like `--bindir=DIR' to specify different values for particular
|
||||
kinds of files. Run `configure --help' for a list of the directories
|
||||
you can set and what kinds of files go in them.
|
||||
|
||||
If the package supports it, you can cause programs to be installed
|
||||
with an extra prefix or suffix on their names by giving `configure' the
|
||||
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
|
||||
|
||||
Optional Features
|
||||
=================
|
||||
|
||||
Some packages pay attention to `--enable-FEATURE' options to
|
||||
`configure', where FEATURE indicates an optional part of the package.
|
||||
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
|
||||
is something like `gnu-as' or `x' (for the X Window System). The
|
||||
`README' should mention any `--enable-' and `--with-' options that the
|
||||
package recognizes.
|
||||
|
||||
For packages that use the X Window System, `configure' can usually
|
||||
find the X include and library files automatically, but if it doesn't,
|
||||
you can use the `configure' options `--x-includes=DIR' and
|
||||
`--x-libraries=DIR' to specify their locations.
|
||||
|
||||
Specifying the System Type
|
||||
==========================
|
||||
|
||||
There may be some features `configure' cannot figure out automatically,
|
||||
but needs to determine by the type of machine the package will run on.
|
||||
Usually, assuming the package is built to be run on the _same_
|
||||
architectures, `configure' can figure that out, but if it prints a
|
||||
message saying it cannot guess the machine type, give it the
|
||||
`--build=TYPE' option. TYPE can either be a short name for the system
|
||||
type, such as `sun4', or a canonical name which has the form:
|
||||
|
||||
CPU-COMPANY-SYSTEM
|
||||
|
||||
where SYSTEM can have one of these forms:
|
||||
|
||||
OS KERNEL-OS
|
||||
|
||||
See the file `config.sub' for the possible values of each field. If
|
||||
`config.sub' isn't included in this package, then this package doesn't
|
||||
need to know the machine type.
|
||||
|
||||
If you are _building_ compiler tools for cross-compiling, you should
|
||||
use the option `--target=TYPE' to select the type of system they will
|
||||
produce code for.
|
||||
|
||||
If you want to _use_ a cross compiler, that generates code for a
|
||||
platform different from the build platform, you should specify the
|
||||
"host" platform (i.e., that on which the generated programs will
|
||||
eventually be run) with `--host=TYPE'.
|
||||
|
||||
Sharing Defaults
|
||||
================
|
||||
|
||||
If you want to set default values for `configure' scripts to share, you
|
||||
can create a site shell script called `config.site' that gives default
|
||||
values for variables like `CC', `cache_file', and `prefix'.
|
||||
`configure' looks for `PREFIX/share/config.site' if it exists, then
|
||||
`PREFIX/etc/config.site' if it exists. Or, you can set the
|
||||
`CONFIG_SITE' environment variable to the location of the site script.
|
||||
A warning: not all `configure' scripts look for a site script.
|
||||
|
||||
Defining Variables
|
||||
==================
|
||||
|
||||
Variables not defined in a site shell script can be set in the
|
||||
environment passed to `configure'. However, some packages may run
|
||||
configure again during the build, and the customized values of these
|
||||
variables may be lost. In order to avoid this problem, you should set
|
||||
them in the `configure' command line, using `VAR=value'. For example:
|
||||
|
||||
./configure CC=/usr/local2/bin/gcc
|
||||
|
||||
causes the specified `gcc' to be used as the C compiler (unless it is
|
||||
overridden in the site shell script). Here is a another example:
|
||||
|
||||
/bin/bash ./configure CONFIG_SHELL=/bin/bash
|
||||
|
||||
Here the `CONFIG_SHELL=/bin/bash' operand causes subsequent
|
||||
configuration-related scripts to be executed by `/bin/bash'.
|
||||
|
||||
`configure' Invocation
|
||||
======================
|
||||
|
||||
`configure' recognizes the following options to control how it operates.
|
||||
|
||||
`--help'
|
||||
`-h'
|
||||
Print a summary of the options to `configure', and exit.
|
||||
|
||||
`--version'
|
||||
`-V'
|
||||
Print the version of Autoconf used to generate the `configure'
|
||||
script, and exit.
|
||||
|
||||
`--cache-file=FILE'
|
||||
Enable the cache: use and save the results of the tests in FILE,
|
||||
traditionally `config.cache'. FILE defaults to `/dev/null' to
|
||||
disable caching.
|
||||
|
||||
`--config-cache'
|
||||
`-C'
|
||||
Alias for `--cache-file=config.cache'.
|
||||
|
||||
`--quiet'
|
||||
`--silent'
|
||||
`-q'
|
||||
Do not print messages saying which checks are being made. To
|
||||
suppress all normal output, redirect it to `/dev/null' (any error
|
||||
messages will still be shown).
|
||||
|
||||
`--srcdir=DIR'
|
||||
Look for the package's source code in directory DIR. Usually
|
||||
`configure' can determine that directory automatically.
|
||||
|
||||
`configure' also accepts some other, not widely useful, options. Run
|
||||
`configure --help' for more details.
|
||||
|
6
utils/iaxclient/lib/libiax2/Makefile.am
Normal file
6
utils/iaxclient/lib/libiax2/Makefile.am
Normal file
|
@ -0,0 +1,6 @@
|
|||
SUBDIRS = src
|
||||
|
||||
bin_SCRIPTS=iax-config
|
||||
BUILT_SCOURCES=iax-config
|
||||
EXTRA_DIST=iax.spec libiax2.vcproj
|
||||
iax-config: iax-config.in
|
12
utils/iaxclient/lib/libiax2/NEWS
Normal file
12
utils/iaxclient/lib/libiax2/NEWS
Normal file
|
@ -0,0 +1,12 @@
|
|||
libiax
|
||||
======
|
||||
|
||||
0.2.3:
|
||||
|
||||
0.2.2:
|
||||
|
||||
0.2.1:
|
||||
|
||||
0.2.0 (Oct 10th, 2001):
|
||||
Initial Release. Hooray! Rejoice! :)
|
||||
|
4
utils/iaxclient/lib/libiax2/README
Normal file
4
utils/iaxclient/lib/libiax2/README
Normal file
|
@ -0,0 +1,4 @@
|
|||
libiax: An implementation of the Inter-Asterisk eXchange protocol distributed
|
||||
under the terms of the GNU Lesser General Public License
|
||||
|
||||
Written by Mark Spencer <markster@linux-support.net>
|
6
utils/iaxclient/lib/libiax2/bootstrap.sh
Executable file
6
utils/iaxclient/lib/libiax2/bootstrap.sh
Executable file
|
@ -0,0 +1,6 @@
|
|||
echo If this fails you probably need to download the latest
|
||||
echo libtool,aclocal,autoconf and automake
|
||||
libtoolize --force
|
||||
aclocal --force
|
||||
autoconf -f
|
||||
automake -acf
|
13
utils/iaxclient/lib/libiax2/build.sh
Executable file
13
utils/iaxclient/lib/libiax2/build.sh
Executable file
|
@ -0,0 +1,13 @@
|
|||
echo configuring automake
|
||||
./bootstrap.sh
|
||||
echo configuring libiax2
|
||||
./configure --enable-newjb
|
||||
echo building libiax2
|
||||
make
|
||||
echo
|
||||
echo
|
||||
echo '##################################################################'
|
||||
echo '# #'
|
||||
echo '# If all is well, enter "make install" to complete installation. #'
|
||||
echo '# #'
|
||||
echo '##################################################################'
|
40
utils/iaxclient/lib/libiax2/configure.in
Normal file
40
utils/iaxclient/lib/libiax2/configure.in
Normal file
|
@ -0,0 +1,40 @@
|
|||
dnl Yo Yo Yo
|
||||
AC_INIT(src/iax.c)
|
||||
AM_INIT_AUTOMAKE([iax], [0.2.3])
|
||||
|
||||
|
||||
dnl Check for various goodies
|
||||
AC_PROG_CC
|
||||
AM_PROG_LIBTOOL
|
||||
dnl LIBTOOL="$LIBTOOL --silent"
|
||||
AC_PROG_INSTALL
|
||||
|
||||
dnl Check for libraries
|
||||
dnl None available
|
||||
|
||||
dnl Check header files
|
||||
AC_HEADER_STDC
|
||||
|
||||
AC_CHECK_FUNCS(gettimeofday)
|
||||
|
||||
AC_SUBST(LIBS)
|
||||
|
||||
AC_ARG_ENABLE(snomhack, [ --enable-snomhack Use slower memset for SNOM phoneem ],,enable_snomhack=no)
|
||||
AC_ARG_ENABLE(extreme_debug, [ --enable-extreme-debug Compile with extreme debugging code enabled ],,enable_extreme_debug=no)
|
||||
if test "$enable_snomhack" = yes ; then
|
||||
AC_DEFINE(SNOM_HACK)
|
||||
fi
|
||||
|
||||
if test "$enable_extreme_debug" = yes ; then
|
||||
AC_DEFINE(EXTREME_DEBUG)
|
||||
fi
|
||||
|
||||
AC_SUBST(IAX_VERSION)
|
||||
|
||||
AC_OUTPUT([
|
||||
Makefile
|
||||
src/Makefile
|
||||
iax.spec
|
||||
iax-config],[case "$CONFIG_FILES" in
|
||||
*iax-config*)chmod +x iax-config;;
|
||||
esac])
|
530
utils/iaxclient/lib/libiax2/depcomp
Executable file
530
utils/iaxclient/lib/libiax2/depcomp
Executable file
|
@ -0,0 +1,530 @@
|
|||
#! /bin/sh
|
||||
# depcomp - compile a program generating dependencies as side-effects
|
||||
|
||||
scriptversion=2005-07-09.11
|
||||
|
||||
# Copyright (C) 1999, 2000, 2003, 2004, 2005 Free Software Foundation, Inc.
|
||||
|
||||
# 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, 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., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
# 02110-1301, USA.
|
||||
|
||||
# As a special exception to the GNU General Public License, if you
|
||||
# distribute this file as part of a program that contains a
|
||||
# configuration script generated by Autoconf, you may include it under
|
||||
# the same distribution terms that you use for the rest of that program.
|
||||
|
||||
# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
|
||||
|
||||
case $1 in
|
||||
'')
|
||||
echo "$0: No command. Try \`$0 --help' for more information." 1>&2
|
||||
exit 1;
|
||||
;;
|
||||
-h | --h*)
|
||||
cat <<\EOF
|
||||
Usage: depcomp [--help] [--version] PROGRAM [ARGS]
|
||||
|
||||
Run PROGRAMS ARGS to compile a file, generating dependencies
|
||||
as side-effects.
|
||||
|
||||
Environment variables:
|
||||
depmode Dependency tracking mode.
|
||||
source Source file read by `PROGRAMS ARGS'.
|
||||
object Object file output by `PROGRAMS ARGS'.
|
||||
DEPDIR directory where to store dependencies.
|
||||
depfile Dependency file to output.
|
||||
tmpdepfile Temporary file to use when outputing dependencies.
|
||||
libtool Whether libtool is used (yes/no).
|
||||
|
||||
Report bugs to <bug-automake@gnu.org>.
|
||||
EOF
|
||||
exit $?
|
||||
;;
|
||||
-v | --v*)
|
||||
echo "depcomp $scriptversion"
|
||||
exit $?
|
||||
;;
|
||||
esac
|
||||
|
||||
if test -z "$depmode" || test -z "$source" || test -z "$object"; then
|
||||
echo "depcomp: Variables source, object and depmode must be set" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
|
||||
depfile=${depfile-`echo "$object" |
|
||||
sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
|
||||
tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
|
||||
|
||||
rm -f "$tmpdepfile"
|
||||
|
||||
# Some modes work just like other modes, but use different flags. We
|
||||
# parameterize here, but still list the modes in the big case below,
|
||||
# to make depend.m4 easier to write. Note that we *cannot* use a case
|
||||
# here, because this file can only contain one case statement.
|
||||
if test "$depmode" = hp; then
|
||||
# HP compiler uses -M and no extra arg.
|
||||
gccflag=-M
|
||||
depmode=gcc
|
||||
fi
|
||||
|
||||
if test "$depmode" = dashXmstdout; then
|
||||
# This is just like dashmstdout with a different argument.
|
||||
dashmflag=-xM
|
||||
depmode=dashmstdout
|
||||
fi
|
||||
|
||||
case "$depmode" in
|
||||
gcc3)
|
||||
## gcc 3 implements dependency tracking that does exactly what
|
||||
## we want. Yay! Note: for some reason libtool 1.4 doesn't like
|
||||
## it if -MD -MP comes after the -MF stuff. Hmm.
|
||||
"$@" -MT "$object" -MD -MP -MF "$tmpdepfile"
|
||||
stat=$?
|
||||
if test $stat -eq 0; then :
|
||||
else
|
||||
rm -f "$tmpdepfile"
|
||||
exit $stat
|
||||
fi
|
||||
mv "$tmpdepfile" "$depfile"
|
||||
;;
|
||||
|
||||
gcc)
|
||||
## There are various ways to get dependency output from gcc. Here's
|
||||
## why we pick this rather obscure method:
|
||||
## - Don't want to use -MD because we'd like the dependencies to end
|
||||
## up in a subdir. Having to rename by hand is ugly.
|
||||
## (We might end up doing this anyway to support other compilers.)
|
||||
## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
|
||||
## -MM, not -M (despite what the docs say).
|
||||
## - Using -M directly means running the compiler twice (even worse
|
||||
## than renaming).
|
||||
if test -z "$gccflag"; then
|
||||
gccflag=-MD,
|
||||
fi
|
||||
"$@" -Wp,"$gccflag$tmpdepfile"
|
||||
stat=$?
|
||||
if test $stat -eq 0; then :
|
||||
else
|
||||
rm -f "$tmpdepfile"
|
||||
exit $stat
|
||||
fi
|
||||
rm -f "$depfile"
|
||||
echo "$object : \\" > "$depfile"
|
||||
alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
|
||||
## The second -e expression handles DOS-style file names with drive letters.
|
||||
sed -e 's/^[^:]*: / /' \
|
||||
-e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
|
||||
## This next piece of magic avoids the `deleted header file' problem.
|
||||
## The problem is that when a header file which appears in a .P file
|
||||
## is deleted, the dependency causes make to die (because there is
|
||||
## typically no way to rebuild the header). We avoid this by adding
|
||||
## dummy dependencies for each header file. Too bad gcc doesn't do
|
||||
## this for us directly.
|
||||
tr ' ' '
|
||||
' < "$tmpdepfile" |
|
||||
## Some versions of gcc put a space before the `:'. On the theory
|
||||
## that the space means something, we add a space to the output as
|
||||
## well.
|
||||
## Some versions of the HPUX 10.20 sed can't process this invocation
|
||||
## correctly. Breaking it into two sed invocations is a workaround.
|
||||
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
hp)
|
||||
# This case exists only to let depend.m4 do its work. It works by
|
||||
# looking at the text of this script. This case will never be run,
|
||||
# since it is checked for above.
|
||||
exit 1
|
||||
;;
|
||||
|
||||
sgi)
|
||||
if test "$libtool" = yes; then
|
||||
"$@" "-Wp,-MDupdate,$tmpdepfile"
|
||||
else
|
||||
"$@" -MDupdate "$tmpdepfile"
|
||||
fi
|
||||
stat=$?
|
||||
if test $stat -eq 0; then :
|
||||
else
|
||||
rm -f "$tmpdepfile"
|
||||
exit $stat
|
||||
fi
|
||||
rm -f "$depfile"
|
||||
|
||||
if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
|
||||
echo "$object : \\" > "$depfile"
|
||||
|
||||
# Clip off the initial element (the dependent). Don't try to be
|
||||
# clever and replace this with sed code, as IRIX sed won't handle
|
||||
# lines with more than a fixed number of characters (4096 in
|
||||
# IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
|
||||
# the IRIX cc adds comments like `#:fec' to the end of the
|
||||
# dependency line.
|
||||
tr ' ' '
|
||||
' < "$tmpdepfile" \
|
||||
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
|
||||
tr '
|
||||
' ' ' >> $depfile
|
||||
echo >> $depfile
|
||||
|
||||
# The second pass generates a dummy entry for each header file.
|
||||
tr ' ' '
|
||||
' < "$tmpdepfile" \
|
||||
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
|
||||
>> $depfile
|
||||
else
|
||||
# The sourcefile does not contain any dependencies, so just
|
||||
# store a dummy comment line, to avoid errors with the Makefile
|
||||
# "include basename.Plo" scheme.
|
||||
echo "#dummy" > "$depfile"
|
||||
fi
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
aix)
|
||||
# The C for AIX Compiler uses -M and outputs the dependencies
|
||||
# in a .u file. In older versions, this file always lives in the
|
||||
# current directory. Also, the AIX compiler puts `$object:' at the
|
||||
# start of each line; $object doesn't have directory information.
|
||||
# Version 6 uses the directory in both cases.
|
||||
stripped=`echo "$object" | sed 's/\(.*\)\..*$/\1/'`
|
||||
tmpdepfile="$stripped.u"
|
||||
if test "$libtool" = yes; then
|
||||
"$@" -Wc,-M
|
||||
else
|
||||
"$@" -M
|
||||
fi
|
||||
stat=$?
|
||||
|
||||
if test -f "$tmpdepfile"; then :
|
||||
else
|
||||
stripped=`echo "$stripped" | sed 's,^.*/,,'`
|
||||
tmpdepfile="$stripped.u"
|
||||
fi
|
||||
|
||||
if test $stat -eq 0; then :
|
||||
else
|
||||
rm -f "$tmpdepfile"
|
||||
exit $stat
|
||||
fi
|
||||
|
||||
if test -f "$tmpdepfile"; then
|
||||
outname="$stripped.o"
|
||||
# Each line is of the form `foo.o: dependent.h'.
|
||||
# Do two passes, one to just change these to
|
||||
# `$object: dependent.h' and one to simply `dependent.h:'.
|
||||
sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile"
|
||||
sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile"
|
||||
else
|
||||
# The sourcefile does not contain any dependencies, so just
|
||||
# store a dummy comment line, to avoid errors with the Makefile
|
||||
# "include basename.Plo" scheme.
|
||||
echo "#dummy" > "$depfile"
|
||||
fi
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
icc)
|
||||
# Intel's C compiler understands `-MD -MF file'. However on
|
||||
# icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c
|
||||
# ICC 7.0 will fill foo.d with something like
|
||||
# foo.o: sub/foo.c
|
||||
# foo.o: sub/foo.h
|
||||
# which is wrong. We want:
|
||||
# sub/foo.o: sub/foo.c
|
||||
# sub/foo.o: sub/foo.h
|
||||
# sub/foo.c:
|
||||
# sub/foo.h:
|
||||
# ICC 7.1 will output
|
||||
# foo.o: sub/foo.c sub/foo.h
|
||||
# and will wrap long lines using \ :
|
||||
# foo.o: sub/foo.c ... \
|
||||
# sub/foo.h ... \
|
||||
# ...
|
||||
|
||||
"$@" -MD -MF "$tmpdepfile"
|
||||
stat=$?
|
||||
if test $stat -eq 0; then :
|
||||
else
|
||||
rm -f "$tmpdepfile"
|
||||
exit $stat
|
||||
fi
|
||||
rm -f "$depfile"
|
||||
# Each line is of the form `foo.o: dependent.h',
|
||||
# or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
|
||||
# Do two passes, one to just change these to
|
||||
# `$object: dependent.h' and one to simply `dependent.h:'.
|
||||
sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
|
||||
# Some versions of the HPUX 10.20 sed can't process this invocation
|
||||
# correctly. Breaking it into two sed invocations is a workaround.
|
||||
sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" |
|
||||
sed -e 's/$/ :/' >> "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
tru64)
|
||||
# The Tru64 compiler uses -MD to generate dependencies as a side
|
||||
# effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
|
||||
# At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
|
||||
# dependencies in `foo.d' instead, so we check for that too.
|
||||
# Subdirectories are respected.
|
||||
dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
|
||||
test "x$dir" = "x$object" && dir=
|
||||
base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
|
||||
|
||||
if test "$libtool" = yes; then
|
||||
# With Tru64 cc, shared objects can also be used to make a
|
||||
# static library. This mecanism is used in libtool 1.4 series to
|
||||
# handle both shared and static libraries in a single compilation.
|
||||
# With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d.
|
||||
#
|
||||
# With libtool 1.5 this exception was removed, and libtool now
|
||||
# generates 2 separate objects for the 2 libraries. These two
|
||||
# compilations output dependencies in in $dir.libs/$base.o.d and
|
||||
# in $dir$base.o.d. We have to check for both files, because
|
||||
# one of the two compilations can be disabled. We should prefer
|
||||
# $dir$base.o.d over $dir.libs/$base.o.d because the latter is
|
||||
# automatically cleaned when .libs/ is deleted, while ignoring
|
||||
# the former would cause a distcleancheck panic.
|
||||
tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4
|
||||
tmpdepfile2=$dir$base.o.d # libtool 1.5
|
||||
tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5
|
||||
tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504
|
||||
"$@" -Wc,-MD
|
||||
else
|
||||
tmpdepfile1=$dir$base.o.d
|
||||
tmpdepfile2=$dir$base.d
|
||||
tmpdepfile3=$dir$base.d
|
||||
tmpdepfile4=$dir$base.d
|
||||
"$@" -MD
|
||||
fi
|
||||
|
||||
stat=$?
|
||||
if test $stat -eq 0; then :
|
||||
else
|
||||
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
|
||||
exit $stat
|
||||
fi
|
||||
|
||||
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
|
||||
do
|
||||
test -f "$tmpdepfile" && break
|
||||
done
|
||||
if test -f "$tmpdepfile"; then
|
||||
sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
|
||||
# That's a tab and a space in the [].
|
||||
sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
|
||||
else
|
||||
echo "#dummy" > "$depfile"
|
||||
fi
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
#nosideeffect)
|
||||
# This comment above is used by automake to tell side-effect
|
||||
# dependency tracking mechanisms from slower ones.
|
||||
|
||||
dashmstdout)
|
||||
# Important note: in order to support this mode, a compiler *must*
|
||||
# always write the preprocessed file to stdout, regardless of -o.
|
||||
"$@" || exit $?
|
||||
|
||||
# Remove the call to Libtool.
|
||||
if test "$libtool" = yes; then
|
||||
while test $1 != '--mode=compile'; do
|
||||
shift
|
||||
done
|
||||
shift
|
||||
fi
|
||||
|
||||
# Remove `-o $object'.
|
||||
IFS=" "
|
||||
for arg
|
||||
do
|
||||
case $arg in
|
||||
-o)
|
||||
shift
|
||||
;;
|
||||
$object)
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
set fnord "$@" "$arg"
|
||||
shift # fnord
|
||||
shift # $arg
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
test -z "$dashmflag" && dashmflag=-M
|
||||
# Require at least two characters before searching for `:'
|
||||
# in the target name. This is to cope with DOS-style filenames:
|
||||
# a dependency such as `c:/foo/bar' could be seen as target `c' otherwise.
|
||||
"$@" $dashmflag |
|
||||
sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile"
|
||||
rm -f "$depfile"
|
||||
cat < "$tmpdepfile" > "$depfile"
|
||||
tr ' ' '
|
||||
' < "$tmpdepfile" | \
|
||||
## Some versions of the HPUX 10.20 sed can't process this invocation
|
||||
## correctly. Breaking it into two sed invocations is a workaround.
|
||||
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
dashXmstdout)
|
||||
# This case only exists to satisfy depend.m4. It is never actually
|
||||
# run, as this mode is specially recognized in the preamble.
|
||||
exit 1
|
||||
;;
|
||||
|
||||
makedepend)
|
||||
"$@" || exit $?
|
||||
# Remove any Libtool call
|
||||
if test "$libtool" = yes; then
|
||||
while test $1 != '--mode=compile'; do
|
||||
shift
|
||||
done
|
||||
shift
|
||||
fi
|
||||
# X makedepend
|
||||
shift
|
||||
cleared=no
|
||||
for arg in "$@"; do
|
||||
case $cleared in
|
||||
no)
|
||||
set ""; shift
|
||||
cleared=yes ;;
|
||||
esac
|
||||
case "$arg" in
|
||||
-D*|-I*)
|
||||
set fnord "$@" "$arg"; shift ;;
|
||||
# Strip any option that makedepend may not understand. Remove
|
||||
# the object too, otherwise makedepend will parse it as a source file.
|
||||
-*|$object)
|
||||
;;
|
||||
*)
|
||||
set fnord "$@" "$arg"; shift ;;
|
||||
esac
|
||||
done
|
||||
obj_suffix="`echo $object | sed 's/^.*\././'`"
|
||||
touch "$tmpdepfile"
|
||||
${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
|
||||
rm -f "$depfile"
|
||||
cat < "$tmpdepfile" > "$depfile"
|
||||
sed '1,2d' "$tmpdepfile" | tr ' ' '
|
||||
' | \
|
||||
## Some versions of the HPUX 10.20 sed can't process this invocation
|
||||
## correctly. Breaking it into two sed invocations is a workaround.
|
||||
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
|
||||
rm -f "$tmpdepfile" "$tmpdepfile".bak
|
||||
;;
|
||||
|
||||
cpp)
|
||||
# Important note: in order to support this mode, a compiler *must*
|
||||
# always write the preprocessed file to stdout.
|
||||
"$@" || exit $?
|
||||
|
||||
# Remove the call to Libtool.
|
||||
if test "$libtool" = yes; then
|
||||
while test $1 != '--mode=compile'; do
|
||||
shift
|
||||
done
|
||||
shift
|
||||
fi
|
||||
|
||||
# Remove `-o $object'.
|
||||
IFS=" "
|
||||
for arg
|
||||
do
|
||||
case $arg in
|
||||
-o)
|
||||
shift
|
||||
;;
|
||||
$object)
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
set fnord "$@" "$arg"
|
||||
shift # fnord
|
||||
shift # $arg
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
"$@" -E |
|
||||
sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
|
||||
-e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
|
||||
sed '$ s: \\$::' > "$tmpdepfile"
|
||||
rm -f "$depfile"
|
||||
echo "$object : \\" > "$depfile"
|
||||
cat < "$tmpdepfile" >> "$depfile"
|
||||
sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
msvisualcpp)
|
||||
# Important note: in order to support this mode, a compiler *must*
|
||||
# always write the preprocessed file to stdout, regardless of -o,
|
||||
# because we must use -o when running libtool.
|
||||
"$@" || exit $?
|
||||
IFS=" "
|
||||
for arg
|
||||
do
|
||||
case "$arg" in
|
||||
"-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
|
||||
set fnord "$@"
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
set fnord "$@" "$arg"
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
"$@" -E |
|
||||
sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile"
|
||||
rm -f "$depfile"
|
||||
echo "$object : \\" > "$depfile"
|
||||
. "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile"
|
||||
echo " " >> "$depfile"
|
||||
. "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
none)
|
||||
exec "$@"
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "Unknown depmode $depmode" 1>&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
exit 0
|
||||
|
||||
# Local Variables:
|
||||
# mode: shell-script
|
||||
# sh-indentation: 2
|
||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-end: "$"
|
||||
# End:
|
20
utils/iaxclient/lib/libiax2/gen.sh
Executable file
20
utils/iaxclient/lib/libiax2/gen.sh
Executable file
|
@ -0,0 +1,20 @@
|
|||
#!/bin/sh
|
||||
|
||||
#
|
||||
# Run this to generate a new configure script and such :)
|
||||
#
|
||||
# -- Rob
|
||||
#
|
||||
|
||||
|
||||
(libtoolize --version) < /dev/null > /dev/null 2>&1 || {
|
||||
echo;
|
||||
echo "You must have libtool installed to compile libiax";
|
||||
echo;
|
||||
exit;
|
||||
}
|
||||
|
||||
libtoolize --copy --force
|
||||
aclocal
|
||||
autoconf
|
||||
automake
|
74
utils/iaxclient/lib/libiax2/iax-config.in
Executable file
74
utils/iaxclient/lib/libiax2/iax-config.in
Executable file
|
@ -0,0 +1,74 @@
|
|||
#!/bin/sh
|
||||
iax_libs="-L/usr/lib -liax"
|
||||
iax_cflags=""
|
||||
|
||||
prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
exec_prefix_set=no
|
||||
|
||||
usage="\
|
||||
Usage: iax-config [--prefix[=DIR]] [--exec-prefix[=DIR]] [--version] [--libs] [--cflags]"
|
||||
|
||||
if test $# -eq 0; then
|
||||
echo "${usage}" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
while test $# -gt 0; do
|
||||
case "$1" in
|
||||
-*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
|
||||
*) optarg= ;;
|
||||
esac
|
||||
|
||||
case $1 in
|
||||
--prefix=*)
|
||||
prefix=$optarg
|
||||
if test $exec_prefix_set = no ; then
|
||||
exec_prefix=$optarg
|
||||
fi
|
||||
;;
|
||||
--prefix)
|
||||
echo $prefix
|
||||
;;
|
||||
--exec-prefix=*)
|
||||
exec_prefix=$optarg
|
||||
exec_prefix_set=yes
|
||||
;;
|
||||
--exec-prefix)
|
||||
echo $exec_prefix
|
||||
;;
|
||||
--version)
|
||||
echo @VERSION@
|
||||
;;
|
||||
--cflags)
|
||||
# if test ${prefix}/include/iax != /usr/include/iax ; then
|
||||
includes=-I${prefix}/include/iax
|
||||
for i in $iax_cflags ; do
|
||||
if test $i = -I${prefix}/include ; then
|
||||
includes=""
|
||||
fi
|
||||
done
|
||||
# fi
|
||||
echo $includes $iax_cflags
|
||||
;;
|
||||
--libs)
|
||||
my_iax_libs=
|
||||
libdirs=-L${exec_prefix}/lib
|
||||
for i in $iax_libs ; do
|
||||
if test $i != -L${exec_prefix}/lib ; then
|
||||
if test -z "$my_iax_libs" ; then
|
||||
my_iax_libs="$i"
|
||||
else
|
||||
my_iax_libs="$my_iax_libs $i"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
echo $libdirs $my_iax_libs
|
||||
;;
|
||||
*)
|
||||
echo "${usage}" 1>&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
91
utils/iaxclient/lib/libiax2/iax.spec.in
Normal file
91
utils/iaxclient/lib/libiax2/iax.spec.in
Normal file
|
@ -0,0 +1,91 @@
|
|||
%define name @PACKAGE@
|
||||
%define version @VERSION@
|
||||
%define release 1
|
||||
%define prefix /usr
|
||||
|
||||
Summary: IAX (Inter Asterisk eXchange) Library
|
||||
Name: %{name}
|
||||
Version: %{version}
|
||||
Release: %{release}
|
||||
Copyright: LGPL
|
||||
Group: Development/Libraries
|
||||
Source: %{name}-%{version}.tar.gz
|
||||
URL: http://www.linux-support.net/
|
||||
Distribution: RedHat Linux
|
||||
Vendor: Linux Support Services
|
||||
Packager: Rob Flynn <rob@linux-support.net>
|
||||
BuildRoot: /var/tmp/%{name}-%{version}-root
|
||||
|
||||
%description
|
||||
Inter Asterisk eXchange, lovingly called IAX (pronounced: eeks), is the protocol used by the Asterisk PBX
|
||||
system for inter-asterisk-communication. Other applications may use libiax to communicate with each other
|
||||
and other asterisk servers. IAX is a high performance, feature rich protocol unrelated
|
||||
to SIP or H.323. Its single-socket design allows it to interoperate with NAT and PAT
|
||||
masquerade firewalls. It supports internationalization, remote dialplans,
|
||||
and voice, HTML, image, DTMF, and video content. For more information see
|
||||
http://www.gnophone.com.
|
||||
|
||||
%package devel
|
||||
Summary: IAX (Inter Asterisk eXchange) Development Package
|
||||
Group: Development/Libraries
|
||||
Requires: iax
|
||||
|
||||
%description devel
|
||||
Inter Asterisk eXchange, lovingly called IAX (pronounced: eeks), is the protocol used by the Asterisk PBX
|
||||
system for inter-asterisk-communication. Other applications may use libiax to communicate with each other
|
||||
and other asterisk servers. IAX is a high performance, feature rich protocol unrelated
|
||||
to SIP or H.323. Its single-socket design allows it to interoperate with NAT and PAT
|
||||
masquerade firewalls. It supports internationalization, remote dialplans,
|
||||
and voice, HTML, image, DTMF, and video content. For more information see
|
||||
http://www.gnophone.com.
|
||||
|
||||
This package contains all of the development files that you will need in order to compile IAX applications.
|
||||
|
||||
%prep
|
||||
|
||||
%setup
|
||||
|
||||
%build
|
||||
CFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=%{prefix} --enable-autoupdate
|
||||
make
|
||||
|
||||
%install
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
make prefix=$RPM_BUILD_ROOT%{prefix} install-strip
|
||||
|
||||
%files
|
||||
%defattr(-,root,root)
|
||||
%doc NEWS COPYING AUTHORS README
|
||||
%{prefix}/lib
|
||||
|
||||
%files devel
|
||||
%defattr(-,root,root)
|
||||
%{prefix}/include/iax
|
||||
%{prefix}/bin/*
|
||||
|
||||
%clean
|
||||
rm -r $RPM_BUILD_ROOT
|
||||
|
||||
%changelog
|
||||
* Tue Nov 13 2001 Rob Flynn <rob@linux-support.net> (0.2.2 release)
|
||||
- HTML Unlink requests
|
||||
- HTML Reject link requests
|
||||
- Text frames
|
||||
|
||||
* Sat Oct 20 2001 Rob Flynn <rob@linux-support.net> (0.2.1 release)
|
||||
- More space for challenge in IAX
|
||||
- Fixed strncpy security bug
|
||||
- Accept larger packets
|
||||
- Handle out of order packets better
|
||||
- Implemented send_url
|
||||
- Added an iax-config script :-)
|
||||
|
||||
* Wed Oct 10 2001 Rob Flynn <rob@linux-support.net> (0.2.0 release)
|
||||
- Initial public release
|
||||
|
||||
%post
|
||||
|
||||
%preun
|
||||
|
||||
%postun
|
||||
|
323
utils/iaxclient/lib/libiax2/install-sh
Executable file
323
utils/iaxclient/lib/libiax2/install-sh
Executable file
|
@ -0,0 +1,323 @@
|
|||
#!/bin/sh
|
||||
# install - install a program, script, or datafile
|
||||
|
||||
scriptversion=2005-05-14.22
|
||||
|
||||
# This originates from X11R5 (mit/util/scripts/install.sh), which was
|
||||
# later released in X11R6 (xc/config/util/install.sh) with the
|
||||
# following copyright and license.
|
||||
#
|
||||
# Copyright (C) 1994 X Consortium
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to
|
||||
# deal in the Software without restriction, including without limitation the
|
||||
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
# sell copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
|
||||
# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
# Except as contained in this notice, the name of the X Consortium shall not
|
||||
# be used in advertising or otherwise to promote the sale, use or other deal-
|
||||
# ings in this Software without prior written authorization from the X Consor-
|
||||
# tium.
|
||||
#
|
||||
#
|
||||
# FSF changes to this file are in the public domain.
|
||||
#
|
||||
# Calling this script install-sh is preferred over install.sh, to prevent
|
||||
# `make' implicit rules from creating a file called install from it
|
||||
# when there is no Makefile.
|
||||
#
|
||||
# This script is compatible with the BSD install script, but was written
|
||||
# from scratch. It can only install one file at a time, a restriction
|
||||
# shared with many OS's install programs.
|
||||
|
||||
# set DOITPROG to echo to test this script
|
||||
|
||||
# Don't use :- since 4.3BSD and earlier shells don't like it.
|
||||
doit="${DOITPROG-}"
|
||||
|
||||
# put in absolute paths if you don't have them in your path; or use env. vars.
|
||||
|
||||
mvprog="${MVPROG-mv}"
|
||||
cpprog="${CPPROG-cp}"
|
||||
chmodprog="${CHMODPROG-chmod}"
|
||||
chownprog="${CHOWNPROG-chown}"
|
||||
chgrpprog="${CHGRPPROG-chgrp}"
|
||||
stripprog="${STRIPPROG-strip}"
|
||||
rmprog="${RMPROG-rm}"
|
||||
mkdirprog="${MKDIRPROG-mkdir}"
|
||||
|
||||
chmodcmd="$chmodprog 0755"
|
||||
chowncmd=
|
||||
chgrpcmd=
|
||||
stripcmd=
|
||||
rmcmd="$rmprog -f"
|
||||
mvcmd="$mvprog"
|
||||
src=
|
||||
dst=
|
||||
dir_arg=
|
||||
dstarg=
|
||||
no_target_directory=
|
||||
|
||||
usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
|
||||
or: $0 [OPTION]... SRCFILES... DIRECTORY
|
||||
or: $0 [OPTION]... -t DIRECTORY SRCFILES...
|
||||
or: $0 [OPTION]... -d DIRECTORIES...
|
||||
|
||||
In the 1st form, copy SRCFILE to DSTFILE.
|
||||
In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
|
||||
In the 4th, create DIRECTORIES.
|
||||
|
||||
Options:
|
||||
-c (ignored)
|
||||
-d create directories instead of installing files.
|
||||
-g GROUP $chgrpprog installed files to GROUP.
|
||||
-m MODE $chmodprog installed files to MODE.
|
||||
-o USER $chownprog installed files to USER.
|
||||
-s $stripprog installed files.
|
||||
-t DIRECTORY install into DIRECTORY.
|
||||
-T report an error if DSTFILE is a directory.
|
||||
--help display this help and exit.
|
||||
--version display version info and exit.
|
||||
|
||||
Environment variables override the default commands:
|
||||
CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG
|
||||
"
|
||||
|
||||
while test -n "$1"; do
|
||||
case $1 in
|
||||
-c) shift
|
||||
continue;;
|
||||
|
||||
-d) dir_arg=true
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-g) chgrpcmd="$chgrpprog $2"
|
||||
shift
|
||||
shift
|
||||
continue;;
|
||||
|
||||
--help) echo "$usage"; exit $?;;
|
||||
|
||||
-m) chmodcmd="$chmodprog $2"
|
||||
shift
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-o) chowncmd="$chownprog $2"
|
||||
shift
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-s) stripcmd=$stripprog
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-t) dstarg=$2
|
||||
shift
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-T) no_target_directory=true
|
||||
shift
|
||||
continue;;
|
||||
|
||||
--version) echo "$0 $scriptversion"; exit $?;;
|
||||
|
||||
*) # When -d is used, all remaining arguments are directories to create.
|
||||
# When -t is used, the destination is already specified.
|
||||
test -n "$dir_arg$dstarg" && break
|
||||
# Otherwise, the last argument is the destination. Remove it from $@.
|
||||
for arg
|
||||
do
|
||||
if test -n "$dstarg"; then
|
||||
# $@ is not empty: it contains at least $arg.
|
||||
set fnord "$@" "$dstarg"
|
||||
shift # fnord
|
||||
fi
|
||||
shift # arg
|
||||
dstarg=$arg
|
||||
done
|
||||
break;;
|
||||
esac
|
||||
done
|
||||
|
||||
if test -z "$1"; then
|
||||
if test -z "$dir_arg"; then
|
||||
echo "$0: no input file specified." >&2
|
||||
exit 1
|
||||
fi
|
||||
# It's OK to call `install-sh -d' without argument.
|
||||
# This can happen when creating conditional directories.
|
||||
exit 0
|
||||
fi
|
||||
|
||||
for src
|
||||
do
|
||||
# Protect names starting with `-'.
|
||||
case $src in
|
||||
-*) src=./$src ;;
|
||||
esac
|
||||
|
||||
if test -n "$dir_arg"; then
|
||||
dst=$src
|
||||
src=
|
||||
|
||||
if test -d "$dst"; then
|
||||
mkdircmd=:
|
||||
chmodcmd=
|
||||
else
|
||||
mkdircmd=$mkdirprog
|
||||
fi
|
||||
else
|
||||
# Waiting for this to be detected by the "$cpprog $src $dsttmp" command
|
||||
# might cause directories to be created, which would be especially bad
|
||||
# if $src (and thus $dsttmp) contains '*'.
|
||||
if test ! -f "$src" && test ! -d "$src"; then
|
||||
echo "$0: $src does not exist." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if test -z "$dstarg"; then
|
||||
echo "$0: no destination specified." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
dst=$dstarg
|
||||
# Protect names starting with `-'.
|
||||
case $dst in
|
||||
-*) dst=./$dst ;;
|
||||
esac
|
||||
|
||||
# If destination is a directory, append the input filename; won't work
|
||||
# if double slashes aren't ignored.
|
||||
if test -d "$dst"; then
|
||||
if test -n "$no_target_directory"; then
|
||||
echo "$0: $dstarg: Is a directory" >&2
|
||||
exit 1
|
||||
fi
|
||||
dst=$dst/`basename "$src"`
|
||||
fi
|
||||
fi
|
||||
|
||||
# This sed command emulates the dirname command.
|
||||
dstdir=`echo "$dst" | sed -e 's,/*$,,;s,[^/]*$,,;s,/*$,,;s,^$,.,'`
|
||||
|
||||
# Make sure that the destination directory exists.
|
||||
|
||||
# Skip lots of stat calls in the usual case.
|
||||
if test ! -d "$dstdir"; then
|
||||
defaultIFS='
|
||||
'
|
||||
IFS="${IFS-$defaultIFS}"
|
||||
|
||||
oIFS=$IFS
|
||||
# Some sh's can't handle IFS=/ for some reason.
|
||||
IFS='%'
|
||||
set x `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'`
|
||||
shift
|
||||
IFS=$oIFS
|
||||
|
||||
pathcomp=
|
||||
|
||||
while test $# -ne 0 ; do
|
||||
pathcomp=$pathcomp$1
|
||||
shift
|
||||
if test ! -d "$pathcomp"; then
|
||||
$mkdirprog "$pathcomp"
|
||||
# mkdir can fail with a `File exist' error in case several
|
||||
# install-sh are creating the directory concurrently. This
|
||||
# is OK.
|
||||
test -d "$pathcomp" || exit
|
||||
fi
|
||||
pathcomp=$pathcomp/
|
||||
done
|
||||
fi
|
||||
|
||||
if test -n "$dir_arg"; then
|
||||
$doit $mkdircmd "$dst" \
|
||||
&& { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \
|
||||
&& { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \
|
||||
&& { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \
|
||||
&& { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; }
|
||||
|
||||
else
|
||||
dstfile=`basename "$dst"`
|
||||
|
||||
# Make a couple of temp file names in the proper directory.
|
||||
dsttmp=$dstdir/_inst.$$_
|
||||
rmtmp=$dstdir/_rm.$$_
|
||||
|
||||
# Trap to clean up those temp files at exit.
|
||||
trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
|
||||
trap '(exit $?); exit' 1 2 13 15
|
||||
|
||||
# Copy the file name to the temp name.
|
||||
$doit $cpprog "$src" "$dsttmp" &&
|
||||
|
||||
# and set any options; do chmod last to preserve setuid bits.
|
||||
#
|
||||
# If any of these fail, we abort the whole thing. If we want to
|
||||
# ignore errors from any of these, just make sure not to ignore
|
||||
# errors from the above "$doit $cpprog $src $dsttmp" command.
|
||||
#
|
||||
{ test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \
|
||||
&& { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \
|
||||
&& { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \
|
||||
&& { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } &&
|
||||
|
||||
# Now rename the file to the real destination.
|
||||
{ $doit $mvcmd -f "$dsttmp" "$dstdir/$dstfile" 2>/dev/null \
|
||||
|| {
|
||||
# The rename failed, perhaps because mv can't rename something else
|
||||
# to itself, or perhaps because mv is so ancient that it does not
|
||||
# support -f.
|
||||
|
||||
# Now remove or move aside any old file at destination location.
|
||||
# We try this two ways since rm can't unlink itself on some
|
||||
# systems and the destination file might be busy for other
|
||||
# reasons. In this case, the final cleanup might fail but the new
|
||||
# file should still install successfully.
|
||||
{
|
||||
if test -f "$dstdir/$dstfile"; then
|
||||
$doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \
|
||||
|| $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \
|
||||
|| {
|
||||
echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2
|
||||
(exit 1); exit 1
|
||||
}
|
||||
else
|
||||
:
|
||||
fi
|
||||
} &&
|
||||
|
||||
# Now rename the file to the real destination.
|
||||
$doit $mvcmd "$dsttmp" "$dstdir/$dstfile"
|
||||
}
|
||||
}
|
||||
fi || { (exit 1); exit 1; }
|
||||
done
|
||||
|
||||
# The final little trick to "correctly" pass the exit status to the exit trap.
|
||||
{
|
||||
(exit 0); exit 0
|
||||
}
|
||||
|
||||
# Local variables:
|
||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-end: "$"
|
||||
# End:
|
242
utils/iaxclient/lib/libiax2/libiax2.vcproj
Normal file
242
utils/iaxclient/lib/libiax2/libiax2.vcproj
Normal file
|
@ -0,0 +1,242 @@
|
|||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="8.00"
|
||||
Name="libiax2"
|
||||
ProjectGUID="{5CC054B7-6DAA-46BF-9A08-3B33B83E8D3E}"
|
||||
RootNamespace="libiax2"
|
||||
Keyword="Win32Proj"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="4"
|
||||
CharacterSet="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
InlineFunctionExpansion="0"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_LIB;LIBIAX;DEBUG_SUPPORT;_CRT_SECURE_NO_DEPRECATE;NEWJB"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="true"
|
||||
DebugInformationFormat="4"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="4"
|
||||
CharacterSet="1"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;LIBIAX"
|
||||
RuntimeLibrary="2"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="true"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\src\iax.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\iax2-parser.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\jitterbuf.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\md5.c"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\src\answer.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\busy.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\dialtone.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\frame.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\iax-client.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\iax.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\iax2-parser.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\iax2.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\jitterbuf.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\md5.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\miniphone.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\options.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\ring10.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\ringtone.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\winpoop.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
|
||||
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
|
||||
>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
360
utils/iaxclient/lib/libiax2/missing
Executable file
360
utils/iaxclient/lib/libiax2/missing
Executable file
|
@ -0,0 +1,360 @@
|
|||
#! /bin/sh
|
||||
# Common stub for a few missing GNU programs while installing.
|
||||
|
||||
scriptversion=2005-06-08.21
|
||||
|
||||
# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005
|
||||
# Free Software Foundation, Inc.
|
||||
# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
|
||||
|
||||
# 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, 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., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
# 02110-1301, USA.
|
||||
|
||||
# As a special exception to the GNU General Public License, if you
|
||||
# distribute this file as part of a program that contains a
|
||||
# configuration script generated by Autoconf, you may include it under
|
||||
# the same distribution terms that you use for the rest of that program.
|
||||
|
||||
if test $# -eq 0; then
|
||||
echo 1>&2 "Try \`$0 --help' for more information"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
run=:
|
||||
|
||||
# In the cases where this matters, `missing' is being run in the
|
||||
# srcdir already.
|
||||
if test -f configure.ac; then
|
||||
configure_ac=configure.ac
|
||||
else
|
||||
configure_ac=configure.in
|
||||
fi
|
||||
|
||||
msg="missing on your system"
|
||||
|
||||
case "$1" in
|
||||
--run)
|
||||
# Try to run requested program, and just exit if it succeeds.
|
||||
run=
|
||||
shift
|
||||
"$@" && exit 0
|
||||
# Exit code 63 means version mismatch. This often happens
|
||||
# when the user try to use an ancient version of a tool on
|
||||
# a file that requires a minimum version. In this case we
|
||||
# we should proceed has if the program had been absent, or
|
||||
# if --run hadn't been passed.
|
||||
if test $? = 63; then
|
||||
run=:
|
||||
msg="probably too old"
|
||||
fi
|
||||
;;
|
||||
|
||||
-h|--h|--he|--hel|--help)
|
||||
echo "\
|
||||
$0 [OPTION]... PROGRAM [ARGUMENT]...
|
||||
|
||||
Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
|
||||
error status if there is no known handling for PROGRAM.
|
||||
|
||||
Options:
|
||||
-h, --help display this help and exit
|
||||
-v, --version output version information and exit
|
||||
--run try to run the given command, and emulate it if it fails
|
||||
|
||||
Supported PROGRAM values:
|
||||
aclocal touch file \`aclocal.m4'
|
||||
autoconf touch file \`configure'
|
||||
autoheader touch file \`config.h.in'
|
||||
automake touch all \`Makefile.in' files
|
||||
bison create \`y.tab.[ch]', if possible, from existing .[ch]
|
||||
flex create \`lex.yy.c', if possible, from existing .c
|
||||
help2man touch the output file
|
||||
lex create \`lex.yy.c', if possible, from existing .c
|
||||
makeinfo touch the output file
|
||||
tar try tar, gnutar, gtar, then tar without non-portable flags
|
||||
yacc create \`y.tab.[ch]', if possible, from existing .[ch]
|
||||
|
||||
Send bug reports to <bug-automake@gnu.org>."
|
||||
exit $?
|
||||
;;
|
||||
|
||||
-v|--v|--ve|--ver|--vers|--versi|--versio|--version)
|
||||
echo "missing $scriptversion (GNU Automake)"
|
||||
exit $?
|
||||
;;
|
||||
|
||||
-*)
|
||||
echo 1>&2 "$0: Unknown \`$1' option"
|
||||
echo 1>&2 "Try \`$0 --help' for more information"
|
||||
exit 1
|
||||
;;
|
||||
|
||||
esac
|
||||
|
||||
# Now exit if we have it, but it failed. Also exit now if we
|
||||
# don't have it and --version was passed (most likely to detect
|
||||
# the program).
|
||||
case "$1" in
|
||||
lex|yacc)
|
||||
# Not GNU programs, they don't have --version.
|
||||
;;
|
||||
|
||||
tar)
|
||||
if test -n "$run"; then
|
||||
echo 1>&2 "ERROR: \`tar' requires --run"
|
||||
exit 1
|
||||
elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
|
||||
*)
|
||||
if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
|
||||
# We have it, but it failed.
|
||||
exit 1
|
||||
elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
|
||||
# Could not run --version or --help. This is probably someone
|
||||
# running `$TOOL --version' or `$TOOL --help' to check whether
|
||||
# $TOOL exists and not knowing $TOOL uses missing.
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
# If it does not exist, or fails to run (possibly an outdated version),
|
||||
# try to emulate it.
|
||||
case "$1" in
|
||||
aclocal*)
|
||||
echo 1>&2 "\
|
||||
WARNING: \`$1' is $msg. You should only need it if
|
||||
you modified \`acinclude.m4' or \`${configure_ac}'. You might want
|
||||
to install the \`Automake' and \`Perl' packages. Grab them from
|
||||
any GNU archive site."
|
||||
touch aclocal.m4
|
||||
;;
|
||||
|
||||
autoconf)
|
||||
echo 1>&2 "\
|
||||
WARNING: \`$1' is $msg. You should only need it if
|
||||
you modified \`${configure_ac}'. You might want to install the
|
||||
\`Autoconf' and \`GNU m4' packages. Grab them from any GNU
|
||||
archive site."
|
||||
touch configure
|
||||
;;
|
||||
|
||||
autoheader)
|
||||
echo 1>&2 "\
|
||||
WARNING: \`$1' is $msg. You should only need it if
|
||||
you modified \`acconfig.h' or \`${configure_ac}'. You might want
|
||||
to install the \`Autoconf' and \`GNU m4' packages. Grab them
|
||||
from any GNU archive site."
|
||||
files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}`
|
||||
test -z "$files" && files="config.h"
|
||||
touch_files=
|
||||
for f in $files; do
|
||||
case "$f" in
|
||||
*:*) touch_files="$touch_files "`echo "$f" |
|
||||
sed -e 's/^[^:]*://' -e 's/:.*//'`;;
|
||||
*) touch_files="$touch_files $f.in";;
|
||||
esac
|
||||
done
|
||||
touch $touch_files
|
||||
;;
|
||||
|
||||
automake*)
|
||||
echo 1>&2 "\
|
||||
WARNING: \`$1' is $msg. You should only need it if
|
||||
you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
|
||||
You might want to install the \`Automake' and \`Perl' packages.
|
||||
Grab them from any GNU archive site."
|
||||
find . -type f -name Makefile.am -print |
|
||||
sed 's/\.am$/.in/' |
|
||||
while read f; do touch "$f"; done
|
||||
;;
|
||||
|
||||
autom4te)
|
||||
echo 1>&2 "\
|
||||
WARNING: \`$1' is needed, but is $msg.
|
||||
You might have modified some files without having the
|
||||
proper tools for further handling them.
|
||||
You can get \`$1' as part of \`Autoconf' from any GNU
|
||||
archive site."
|
||||
|
||||
file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'`
|
||||
test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'`
|
||||
if test -f "$file"; then
|
||||
touch $file
|
||||
else
|
||||
test -z "$file" || exec >$file
|
||||
echo "#! /bin/sh"
|
||||
echo "# Created by GNU Automake missing as a replacement of"
|
||||
echo "# $ $@"
|
||||
echo "exit 0"
|
||||
chmod +x $file
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
|
||||
bison|yacc)
|
||||
echo 1>&2 "\
|
||||
WARNING: \`$1' $msg. You should only need it if
|
||||
you modified a \`.y' file. You may need the \`Bison' package
|
||||
in order for those modifications to take effect. You can get
|
||||
\`Bison' from any GNU archive site."
|
||||
rm -f y.tab.c y.tab.h
|
||||
if [ $# -ne 1 ]; then
|
||||
eval LASTARG="\${$#}"
|
||||
case "$LASTARG" in
|
||||
*.y)
|
||||
SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
|
||||
if [ -f "$SRCFILE" ]; then
|
||||
cp "$SRCFILE" y.tab.c
|
||||
fi
|
||||
SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
|
||||
if [ -f "$SRCFILE" ]; then
|
||||
cp "$SRCFILE" y.tab.h
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
if [ ! -f y.tab.h ]; then
|
||||
echo >y.tab.h
|
||||
fi
|
||||
if [ ! -f y.tab.c ]; then
|
||||
echo 'main() { return 0; }' >y.tab.c
|
||||
fi
|
||||
;;
|
||||
|
||||
lex|flex)
|
||||
echo 1>&2 "\
|
||||
WARNING: \`$1' is $msg. You should only need it if
|
||||
you modified a \`.l' file. You may need the \`Flex' package
|
||||
in order for those modifications to take effect. You can get
|
||||
\`Flex' from any GNU archive site."
|
||||
rm -f lex.yy.c
|
||||
if [ $# -ne 1 ]; then
|
||||
eval LASTARG="\${$#}"
|
||||
case "$LASTARG" in
|
||||
*.l)
|
||||
SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
|
||||
if [ -f "$SRCFILE" ]; then
|
||||
cp "$SRCFILE" lex.yy.c
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
if [ ! -f lex.yy.c ]; then
|
||||
echo 'main() { return 0; }' >lex.yy.c
|
||||
fi
|
||||
;;
|
||||
|
||||
help2man)
|
||||
echo 1>&2 "\
|
||||
WARNING: \`$1' is $msg. You should only need it if
|
||||
you modified a dependency of a manual page. You may need the
|
||||
\`Help2man' package in order for those modifications to take
|
||||
effect. You can get \`Help2man' from any GNU archive site."
|
||||
|
||||
file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
|
||||
if test -z "$file"; then
|
||||
file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'`
|
||||
fi
|
||||
if [ -f "$file" ]; then
|
||||
touch $file
|
||||
else
|
||||
test -z "$file" || exec >$file
|
||||
echo ".ab help2man is required to generate this page"
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
|
||||
makeinfo)
|
||||
echo 1>&2 "\
|
||||
WARNING: \`$1' is $msg. You should only need it if
|
||||
you modified a \`.texi' or \`.texinfo' file, or any other file
|
||||
indirectly affecting the aspect of the manual. The spurious
|
||||
call might also be the consequence of using a buggy \`make' (AIX,
|
||||
DU, IRIX). You might want to install the \`Texinfo' package or
|
||||
the \`GNU make' package. Grab either from any GNU archive site."
|
||||
# The file to touch is that specified with -o ...
|
||||
file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
|
||||
if test -z "$file"; then
|
||||
# ... or it is the one specified with @setfilename ...
|
||||
infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
|
||||
file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $infile`
|
||||
# ... or it is derived from the source name (dir/f.texi becomes f.info)
|
||||
test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info
|
||||
fi
|
||||
# If the file does not exist, the user really needs makeinfo;
|
||||
# let's fail without touching anything.
|
||||
test -f $file || exit 1
|
||||
touch $file
|
||||
;;
|
||||
|
||||
tar)
|
||||
shift
|
||||
|
||||
# We have already tried tar in the generic part.
|
||||
# Look for gnutar/gtar before invocation to avoid ugly error
|
||||
# messages.
|
||||
if (gnutar --version > /dev/null 2>&1); then
|
||||
gnutar "$@" && exit 0
|
||||
fi
|
||||
if (gtar --version > /dev/null 2>&1); then
|
||||
gtar "$@" && exit 0
|
||||
fi
|
||||
firstarg="$1"
|
||||
if shift; then
|
||||
case "$firstarg" in
|
||||
*o*)
|
||||
firstarg=`echo "$firstarg" | sed s/o//`
|
||||
tar "$firstarg" "$@" && exit 0
|
||||
;;
|
||||
esac
|
||||
case "$firstarg" in
|
||||
*h*)
|
||||
firstarg=`echo "$firstarg" | sed s/h//`
|
||||
tar "$firstarg" "$@" && exit 0
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
echo 1>&2 "\
|
||||
WARNING: I can't seem to be able to run \`tar' with the given arguments.
|
||||
You may want to install GNU tar or Free paxutils, or check the
|
||||
command line arguments."
|
||||
exit 1
|
||||
;;
|
||||
|
||||
*)
|
||||
echo 1>&2 "\
|
||||
WARNING: \`$1' is needed, and is $msg.
|
||||
You might have modified some files without having the
|
||||
proper tools for further handling them. Check the \`README' file,
|
||||
it often tells you about the needed prerequisites for installing
|
||||
this package. You may also peek at any GNU archive site, in case
|
||||
some other package would contain this missing \`$1' program."
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
exit 0
|
||||
|
||||
# Local variables:
|
||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-end: "$"
|
||||
# End:
|
158
utils/iaxclient/lib/libiax2/mkinstalldirs
Executable file
158
utils/iaxclient/lib/libiax2/mkinstalldirs
Executable file
|
@ -0,0 +1,158 @@
|
|||
#! /bin/sh
|
||||
# mkinstalldirs --- make directory hierarchy
|
||||
|
||||
scriptversion=2005-06-29.22
|
||||
|
||||
# Original author: Noah Friedman <friedman@prep.ai.mit.edu>
|
||||
# Created: 1993-05-16
|
||||
# Public domain.
|
||||
#
|
||||
# This file is maintained in Automake, please report
|
||||
# bugs to <bug-automake@gnu.org> or send patches to
|
||||
# <automake-patches@gnu.org>.
|
||||
|
||||
errstatus=0
|
||||
dirmode=
|
||||
|
||||
usage="\
|
||||
Usage: mkinstalldirs [-h] [--help] [--version] [-m MODE] DIR ...
|
||||
|
||||
Create each directory DIR (with mode MODE, if specified), including all
|
||||
leading file name components.
|
||||
|
||||
Report bugs to <bug-automake@gnu.org>."
|
||||
|
||||
# process command line arguments
|
||||
while test $# -gt 0 ; do
|
||||
case $1 in
|
||||
-h | --help | --h*) # -h for help
|
||||
echo "$usage"
|
||||
exit $?
|
||||
;;
|
||||
-m) # -m PERM arg
|
||||
shift
|
||||
test $# -eq 0 && { echo "$usage" 1>&2; exit 1; }
|
||||
dirmode=$1
|
||||
shift
|
||||
;;
|
||||
--version)
|
||||
echo "$0 $scriptversion"
|
||||
exit $?
|
||||
;;
|
||||
--) # stop option processing
|
||||
shift
|
||||
break
|
||||
;;
|
||||
-*) # unknown option
|
||||
echo "$usage" 1>&2
|
||||
exit 1
|
||||
;;
|
||||
*) # first non-opt arg
|
||||
break
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
for file
|
||||
do
|
||||
if test -d "$file"; then
|
||||
shift
|
||||
else
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
case $# in
|
||||
0) exit 0 ;;
|
||||
esac
|
||||
|
||||
# Solaris 8's mkdir -p isn't thread-safe. If you mkdir -p a/b and
|
||||
# mkdir -p a/c at the same time, both will detect that a is missing,
|
||||
# one will create a, then the other will try to create a and die with
|
||||
# a "File exists" error. This is a problem when calling mkinstalldirs
|
||||
# from a parallel make. We use --version in the probe to restrict
|
||||
# ourselves to GNU mkdir, which is thread-safe.
|
||||
case $dirmode in
|
||||
'')
|
||||
if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then
|
||||
echo "mkdir -p -- $*"
|
||||
exec mkdir -p -- "$@"
|
||||
else
|
||||
# On NextStep and OpenStep, the `mkdir' command does not
|
||||
# recognize any option. It will interpret all options as
|
||||
# directories to create, and then abort because `.' already
|
||||
# exists.
|
||||
test -d ./-p && rmdir ./-p
|
||||
test -d ./--version && rmdir ./--version
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
if mkdir -m "$dirmode" -p --version . >/dev/null 2>&1 &&
|
||||
test ! -d ./--version; then
|
||||
echo "mkdir -m $dirmode -p -- $*"
|
||||
exec mkdir -m "$dirmode" -p -- "$@"
|
||||
else
|
||||
# Clean up after NextStep and OpenStep mkdir.
|
||||
for d in ./-m ./-p ./--version "./$dirmode";
|
||||
do
|
||||
test -d $d && rmdir $d
|
||||
done
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
for file
|
||||
do
|
||||
case $file in
|
||||
/*) pathcomp=/ ;;
|
||||
*) pathcomp= ;;
|
||||
esac
|
||||
oIFS=$IFS
|
||||
IFS=/
|
||||
set fnord $file
|
||||
shift
|
||||
IFS=$oIFS
|
||||
|
||||
for d
|
||||
do
|
||||
test "x$d" = x && continue
|
||||
|
||||
pathcomp=$pathcomp$d
|
||||
case $pathcomp in
|
||||
-*) pathcomp=./$pathcomp ;;
|
||||
esac
|
||||
|
||||
if test ! -d "$pathcomp"; then
|
||||
echo "mkdir $pathcomp"
|
||||
|
||||
mkdir "$pathcomp" || lasterr=$?
|
||||
|
||||
if test ! -d "$pathcomp"; then
|
||||
errstatus=$lasterr
|
||||
else
|
||||
if test ! -z "$dirmode"; then
|
||||
echo "chmod $dirmode $pathcomp"
|
||||
lasterr=
|
||||
chmod "$dirmode" "$pathcomp" || lasterr=$?
|
||||
|
||||
if test ! -z "$lasterr"; then
|
||||
errstatus=$lasterr
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
pathcomp=$pathcomp/
|
||||
done
|
||||
done
|
||||
|
||||
exit $errstatus
|
||||
|
||||
# Local Variables:
|
||||
# mode: shell-script
|
||||
# sh-indentation: 2
|
||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-end: "$"
|
||||
# End:
|
22
utils/iaxclient/lib/libiax2/src/Makefile.am
Normal file
22
utils/iaxclient/lib/libiax2/src/Makefile.am
Normal file
|
@ -0,0 +1,22 @@
|
|||
AM_CFLAGS = -Wall -O2
|
||||
AM_CFLAGS += -g -Wall -Wstrict-prototypes -I .
|
||||
AM_CFLAGS += -DDEBUG_SUPPORT -DLIBIAX
|
||||
AM_CFLAGS += -fsigned-char
|
||||
# -DDEBUG_DEFAULT
|
||||
AM_CFLAGS += $(UCFLAGS)
|
||||
|
||||
|
||||
pkgdir = $(libdir)
|
||||
pkg_LTLIBRARIES=libiax.la
|
||||
libiax_la_SOURCES = iax2-parser.c iax.c md5.c jitterbuf.c
|
||||
EXTRA_DIST = md5.h frame.h iax-client.h iax2.h iax2-parser.h jitterbuf.h
|
||||
|
||||
install-data-local:
|
||||
mkdir -p $(includedir)/iax
|
||||
install -m 644 md5.h $(includedir)/iax
|
||||
install -m 644 frame.h $(includedir)/iax
|
||||
install -m 644 iax.h $(includedir)/iax
|
||||
install -m 644 iax2.h $(includedir)/iax
|
||||
install -m 644 iax2-parser.h $(includedir)/iax
|
||||
install -m 644 iax-client.h $(includedir)/iax
|
||||
|
237
utils/iaxclient/lib/libiax2/src/answer.h
Normal file
237
utils/iaxclient/lib/libiax2/src/answer.h
Normal file
|
@ -0,0 +1,237 @@
|
|||
/*
|
||||
* Signed 16-bit audio data
|
||||
*
|
||||
* Source: answer.raw
|
||||
*
|
||||
* Copyright (C) 1999, Mark Spencer and Linux Support Services
|
||||
*
|
||||
* Distributed under the terms of the GNU General Public License
|
||||
*
|
||||
*/
|
||||
|
||||
static signed short answer[] = {
|
||||
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
|
||||
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
|
||||
000000, 000000, 0x19b7, 0x0245, 0xeee5, 0xb875, 0xd9a4, 0x6018, 0x660a, 0xc3c6,
|
||||
0x8741, 0xff55, 0x4c2e, 0x2146, 0xfed2, 0xf079, 0xcbd4, 0xe561, 0x3c41, 0x3166,
|
||||
0xd425, 0xdc59, 0x2748, 0x087d, 0xc72b, 0xfe3a, 0x4681, 0x14c6, 0xcf45, 0xdd38,
|
||||
0xf8dd, 0x0a39, 0x3a5a, 0x32b9, 0xbfec, 0x957f, 0x15a3, 0x70f4, 0x1d95, 0xbfc4,
|
||||
0xd367, 0xfda0, 0x0dc0, 0x29eb, 0x1fc2, 0xd684, 0xcab1, 0x19c7, 0x29ef, 0xe679,
|
||||
0xe9d0, 0x2b82, 0x151a, 0xca9f, 0xdb68, 0x1f4a, 0x271c, 0x0e2a, 0xfb32, 0xd1b2,
|
||||
0xc8ff, 0x2382, 0x6380, 0x0a52, 0xa118, 0xccbf, 0x2ddc, 0x33fd, 0x0964, 0xf2a4,
|
||||
0xdd81, 0xe092, 0x1a00, 0x325c, 0xf5e3, 0xd6a1, 0x0b6c, 0x1c75, 0xe4f8, 0xe07c,
|
||||
0x2082, 0x2b3e, 0xf445, 0xdaa9, 0xea13, 0xff3c, 0x245c, 0x35c1, 0xf308, 0xab53,
|
||||
0xdf59, 0x4698, 0x3f3b, 0xe7f7, 0xca84, 0xed4d, 0x0c3f, 0x1e94, 0x1c2d, 0xf06f,
|
||||
0xd4df, 0xff34, 0x23d8, 0x001e, 0xe3f1, 0x0b15, 0x2113, 0xf3fd, 0xd768, 0xf9a0,
|
||||
0x1d31, 0x1c6e, 0x0797, 0xe3a0, 0xce6c, 0xfd7b, 0x422a, 0x2c4c, 0xd364, 0xbf42,
|
||||
0x0278, 0x303e, 0x1c51, 0xf737, 0xe25a, 0xe75f, 0x0a8f, 0x22ab, 0x05f4, 0xe3f9,
|
||||
0xf8c4, 0x1705, 0x0162, 0xe49f, 0xfb8b, 0x1e2b, 0x13ac, 0xf044, 0xe07b, 0xf01a,
|
||||
0x1567, 0x2cbf, 0x0b75, 0xd01b, 0xd206, 0x1563, 0x38d7, 0x0f2e, 0xdb32, 0xdc30,
|
||||
0x023b, 0x1e44, 0x16eb, 0xf5f7, 0xe425, 0xfa33, 0x14d5, 0x0968, 0xeff2, 0xf762,
|
||||
0x1137, 0x0e59, 0xf13a, 0xe651, 0xff41, 0x1d60, 0x18fd, 0xf1e6, 0xd75f, 0xf097,
|
||||
0x20ec, 0x27fa, 0xfba4, 0xd5b8, 0xe68e, 0x1657, 0x2518, 0x04f6, 0xe5a3, 0xe976,
|
||||
0x0578, 0x18fa, 0x0a92, 0xec0a, 0xef2a, 0x111f, 0x12f4, 0xeec3, 0xe95e, 0x0d3a,
|
||||
0x18fd, 0xff72, 0xeefc, 0xf114, 0xfaaa, 0x14ee, 0x21db, 0xf56e, 0xcb49, 0xf621,
|
||||
0x3323, 0x1947, 0xe017, 0xe7e9, 0x0819, 0x0707, 0x084c, 0x0f57, 0xf152, 0xdf92,
|
||||
0x104a, 0x28eb, 0xedcc, 0xd4ad, 0x1415, 0x296d, 0xed9a, 0xdf57, 0x0cc2, 0x0d95,
|
||||
0xf7b5, 0x0deb, 0x0b34, 0xd713, 0xea08, 0x38d6, 0x216d, 0xc727, 0xdc32, 0x2cd2,
|
||||
0x1822, 0xe2d5, 0xfeb3, 0x106c, 0xe6e5, 0xf81e, 0x2fe8, 0x01af, 0xc180, 0x037a,
|
||||
0x42d8, 0xf88d, 0xc344, 0x0a4f, 0x2c4e, 0xf19d, 0xebeb, 0x162c, 0xf9e9, 0xde93,
|
||||
0x1b56, 0x2c60, 0xd8aa, 0xce3e, 0x2a41, 0x2eeb, 0xdab1, 0xde32, 0x1c32, 0x0aba,
|
||||
0xeabe, 0x1008, 0x136d, 0xda2f, 0xec3b, 0x31dd, 0x1130, 0xca79, 0xf5b8, 0x3423,
|
||||
0x0274, 0xd27d, 0x035e, 0x1e68, 0xf641, 0xf904, 0x1691, 0xef7d, 0xd57a, 0x1c3b,
|
||||
0x3c23, 0xe881, 0xc274, 0x0af5, 0x2962, 0xfa34, 0xf676, 0x0f71, 0xefcc, 0xe01f,
|
||||
0x19e7, 0x276f, 0xe694, 0xe134, 0x1c3a, 0x0e8b, 0xd8e7, 0xfa81, 0x2f8b, 0x07c5,
|
||||
0xd904, 0xf6fa, 0x0ca5, 0xf9a2, 0x0dc7, 0x2623, 0xec54, 0xbe23, 0x02b6, 0x4296,
|
||||
0x10cd, 0xda61, 0xf11c, 0x0103, 0xf41c, 0x10b4, 0x2a03, 0xf63c, 0xce1a, 0xfdbd,
|
||||
0x1fb4, 0xfc51, 0xf727, 0x1c8a, 0x04ff, 0xcf41, 0xec05, 0x2913, 0x1ce8, 0xf70c,
|
||||
0xf744, 0xede8, 0xdd77, 0x0d99, 0x43f1, 0x119c, 0xc14f, 0xd60e, 0x17cb, 0x1e19,
|
||||
0x0d4e, 0x0c95, 0xeed1, 0xcdf4, 0xf7a5, 0x331f, 0x1cd0, 0xeb17, 0xf082, 0xfb19,
|
||||
0xe899, 0xfdeb, 0x323c, 0x2036, 0xdad3, 0xd134, 0xfd03, 0x1345, 0x1c10, 0x2239,
|
||||
0xf656, 0xbc22, 0xdc3f, 0x3392, 0x3d59, 0xfd77, 0xdb4d, 0xe23f, 0xedbe, 0x0f7e,
|
||||
0x35cc, 0x1947, 0xd5dc, 0xd1bf, 0x035d, 0x16fc, 0x1174, 0x1675, 0x0249, 0xd2d4,
|
||||
0xd851, 0x184d, 0x32fe, 0x0f91, 0xee14, 0xe1e6, 0xdf9b, 0x016b, 0x3668, 0x2b2b,
|
||||
0xe20c, 0xc554, 0xf257, 0x1c05, 0x1fc5, 0x14f0, 0xf891, 0xd41c, 0xdf83, 0x1865,
|
||||
0x2de1, 0x0b16, 0xed58, 0xea0c, 0xea79, 0xfbd9, 0x22af, 0x2732, 0xf62f, 0xd389,
|
||||
0xe7d9, 0x0b39, 0x1cdc, 0x1de3, 0x038a, 0xd809, 0xd5f7, 0x0b55, 0x305e, 0x1910,
|
||||
0xf02e, 0xe089, 0xe7c7, 0x0195, 0x2265, 0x21da, 0xf743, 0xd8f2, 0xe978, 0x09a1,
|
||||
0x190a, 0x17c5, 0x045a, 0xe46d, 0xdd06, 0xffb2, 0x2293, 0x1cfe, 0xfd4d, 0xe4f9,
|
||||
0xe310, 0xfaf1, 0x1d22, 0x2376, 0x0113, 0xde3a, 0xe21b, 0x0204, 0x1ba1, 0x1bd6,
|
||||
0x0333, 0xe563, 0xe104, 0xfd51, 0x1bc1, 0x1ccf, 0x0285, 0xe757, 0xe35e, 0xfaf2,
|
||||
0x185d, 0x1d46, 0x06b7, 0xec13, 0xe108, 0xef6e, 0x121d, 0x2a17, 0x16a6, 0xe32c,
|
||||
0xc9a9, 0xf070, 0x2f48, 0x3788, 0xfa4e, 0xc32a, 0xd9c2, 0x1fa1, 0x36fe, 0x07fa,
|
||||
0xd9e4, 0xe577, 0x0e5e, 0x1755, 0xfb53, 0xed71, 0x0540, 0x19e0, 0x0301, 0xdc97,
|
||||
0xe391, 0x1937, 0x367c, 0x0bc9, 0xca4c, 0xc96b, 0x105d, 0x461f, 0x2416, 0xd481,
|
||||
0xbc97, 0xf8b7, 0x39af, 0x2ec9, 0xecc6, 0xcb50, 0xeee3, 0x1ffe, 0x1e8e, 0xf700,
|
||||
0xe66a, 0xff58, 0x149f, 0x02e5, 0xe792, 0xf2d8, 0x1a4d, 0x225a, 0xf642, 0xce7f,
|
||||
0xe6a6, 0x25e2, 0x38f5, 0x01d0, 0xc50f, 0xd243, 0x19bd, 0x3fc6, 0x14f0, 0xd2d7,
|
||||
0xcdb6, 0x069a, 0x2ffe, 0x1847, 0xe6f8, 0xdf0a, 0x0337, 0x1a90, 0x067a, 0xeb5b,
|
||||
0xf541, 0x143b, 0x14f2, 0xf092, 0xdc02, 0xfb91, 0x28a3, 0x2274, 0xeaa8, 0xc9e7,
|
||||
0xef48, 0x2d01, 0x322e, 0xf6d2, 0xc7cb, 0xe13b, 0x1fda, 0x3217, 0x0458, 0xd690,
|
||||
0xe2bf, 0x11c4, 0x21d5, 0x0291, 0xe5c8, 0xf3a9, 0x12ba, 0x11aa, 0xf22b, 0xe627,
|
||||
0x03ec, 0x219a, 0x1036, 0xe2f2, 0xd93f, 0x059c, 0x2ed6, 0x1b75, 0xe227, 0xce55,
|
||||
0xfb19, 0x2de0, 0x2477, 0xed08, 0xd148, 0xf307, 0x21d4, 0x2002, 0xf543, 0xdeac,
|
||||
0xf7f9, 0x18a9, 0x11d6, 0xf0ef, 0xe8e4, 0x05ea, 0x1ba5, 0x0727, 0xe448, 0xe748,
|
||||
0x100e, 0x265e, 0x07fc, 0xdbae, 0xde78, 0x0efa, 0x2ce0, 0x0f94, 0xddf1, 0xd9ea,
|
||||
0x0797, 0x28f6, 0x12eb, 0xe60c, 0xdf46, 0x0469, 0x1fbb, 0x0ced, 0xe9f6, 0xe95f,
|
||||
0x09fe, 0x1ab9, 0x02cb, 0xe5a4, 0xef2a, 0x1327, 0x1d7b, 0xfd07, 0xde3d, 0xed9c,
|
||||
0x17e5, 0x22e7, 0xfe3a, 0xdb38, 0xe9b9, 0x161a, 0x2416, 0x0175, 0xde3d, 0xe9de,
|
||||
0x1294, 0x1fc9, 0x00ea, 0xe2a7, 0xeee2, 0x1298, 0x1a7d, 0xfc1d, 0xe3bb, 0xf47a,
|
||||
0x1642, 0x185e, 0xf727, 0xe1af, 0xf709, 0x19c3, 0x18e7, 0xf50d, 0xe010, 0xf75b,
|
||||
0x1a9c, 0x18d8, 0xf4c5, 0xe0c9, 0xf865, 0x1a1c, 0x16d5, 0xf3a6, 0xe257, 0xfaf2,
|
||||
0x1a44, 0x14d5, 0xf34f, 0xe4b6, 0xfc77, 0x17d5, 0x0ff8, 0xf133, 0xe8b7, 0x0344,
|
||||
0x1a37, 0x0ad5, 0xe95e, 0xe61a, 0x08a5, 0x227e, 0x0e33, 0xe4a7, 0xdd70, 0x03b0,
|
||||
0x25f4, 0x17b2, 0xec0a, 0xdb4e, 0xf898, 0x1ba3, 0x18f6, 0xf973, 0xe87f, 0xf77a,
|
||||
0x0b93, 0x096c, 0xfb0e, 0xfb03, 0x0896, 0x0940, 0xf51d, 0xe904, 0xfdc7, 0x1dda,
|
||||
0x1bf9, 0xf29b, 0xd37f, 0xea1b, 0x1f37, 0x3175, 0x07eb, 0xd3f7, 0xd46b, 0x077d,
|
||||
0x2eeb, 0x1e67, 0xeeae, 0xd8c7, 0xef85, 0x1119, 0x18d3, 0x088e, 0xf953, 0xf5ad,
|
||||
0xf556, 0xf63d, 0x0234, 0x167a, 0x19a1, 0xfbf9, 0xd873, 0xdd4b, 0x0f06, 0x3748,
|
||||
0x21e6, 0xe181, 0xc032, 0xe79a, 0x2bec, 0x3e76, 0x0b1b, 0xce41, 0xcb23, 0xff96,
|
||||
0x2d79, 0x26d1, 0xfcc7, 0xdf8a, 0xe525, 0xfd83, 0x10f1, 0x16d7, 0x0f50, 0xfaea,
|
||||
0xe3f1, 0xe20f, 0x0158, 0x27d9, 0x2866, 0xf96f, 0xcb34, 0xd563, 0x11d6, 0x3d25,
|
||||
0x2424, 0xe254, 0xc2c9, 0xe7cd, 0x248d, 0x34f5, 0x0c42, 0xdcd0, 0xd827, 0xfa65,
|
||||
0x19eb, 0x1b50, 0x0721, 0xf396, 0xeb9c, 0xefde, 0x0016, 0x1594, 0x1cc1, 0x0658,
|
||||
0xe22b, 0xd852, 0xfb3e, 0x2923, 0x2c78, 0xfc87, 0xcdb5, 0xd69c, 0x0e3c, 0x3527,
|
||||
0x201f, 0xe993, 0xcf9e, 0xeb21, 0x183f, 0x25ea, 0x0c93, 0xed4d, 0xe5f9, 0xf548,
|
||||
0x07fb, 0x117c, 0x0ff2, 0x0398, 0xf08c, 0xe628, 0xf489, 0x143b, 0x2419, 0x0ccf,
|
||||
0xe2cc, 0xd5a6, 0xf861, 0x2615, 0x2a1b, 0xfeb4, 0xd543, 0xdc53, 0x09b4, 0x2901,
|
||||
0x19ff, 0xf24a, 0xde86, 0xeec4, 0x0b7b, 0x1733, 0x0d0a, 0xfc24, 0xf1bb, 0xf110,
|
||||
0xfa03, 0x0a0f, 0x15d4, 0x0e21, 0xf435, 0xe17e, 0xee90, 0x1225, 0x2527, 0x0efa,
|
||||
0xe61f, 0xd916, 0xf7b8, 0x1f50, 0x2326, 0x0099, 0xe01e, 0xe473, 0x0491, 0x1b37,
|
||||
0x1360, 0xfb17, 0xecd9, 0xf20d, 0x0051, 0x0aec, 0x0d4a, 0x073d, 0xfa5a, 0xeeb8,
|
||||
0xf165, 0x0516, 0x17dc, 0x12da, 0xf71b, 0xe213, 0xed85, 0x0eef, 0x20c8, 0x0e09,
|
||||
0xebcc, 0xe0d4, 0xf848, 0x1637, 0x19d6, 0x026b, 0xec09, 0xed00, 0xff9b, 0x0e5a,
|
||||
0x0d6b, 0x026c, 0xf865, 0xf4da, 0xf888, 0x025a, 0x0cbb, 0x0d53, 0xff96, 0xeefa,
|
||||
0xee80, 0x021c, 0x15d6, 0x126a, 0xf9c1, 0xe724, 0xf017, 0x0aa1, 0x18b6, 0x0b4e,
|
||||
0xf2d7, 0xea91, 0xf957, 0x0cac, 0x1061, 0x03f4, 0xf6ad, 0xf476, 0xfbdf, 0x0489,
|
||||
0x08b1, 0x06df, 0xffcf, 0xf766, 0xf537, 0xfddf, 0x0ad4, 0x0e15, 0x01da, 0xf205,
|
||||
0xf0a0, 0x0082, 0x1066, 0x0e41, 0xfc71, 0xef1b, 0xf4ad, 0x05cd, 0x0f32, 0x07ed,
|
||||
0xf9c8, 0xf401, 0xfa93, 0x04af, 0x088c, 0x04a7, 0xfe15, 0xf9f1, 0xfa64, 0xff1e,
|
||||
0x0539, 0x078c, 0x02af, 0xfa1a, 0xf69d, 0xfd09, 0x075b, 0x0a3d, 0x01f2, 0xf761,
|
||||
0xf642, 0xffa7, 0x08f3, 0x0830, 0xff05, 0xf7db, 0xf9bc, 0x0174, 0x068b, 0x04b2,
|
||||
0xfeff, 0xfb39, 0xfc1a, 000000, 0x0371, 0x03d7, 0x00fe, 0xfd37, 0xfbe0, 0xfe78,
|
||||
0x02af, 0x044a, 0x0180, 0xfd43, 0xfc00, 0xfed1, 0x02aa, 0x0346, 0x00dd, 0xfde0,
|
||||
0xfbfe, 0x0114, 0x0987, 0x04bc, 0xf49d, 0xf23a, 0x06ab, 0x162e, 0x0544, 0xe76b,
|
||||
0xea25, 0x1015, 0x2474, 0x0431, 0xd7d3, 0xe1ec, 0x1923, 0x2df5, 0x01cd, 0xd386,
|
||||
0xe3d9, 0x1b9d, 0x2c62, 0xfeb8, 0xd31a, 0xe6ba, 0x1dbd, 0x2abb, 0xfbab, 0xd2ed,
|
||||
0xe9ab, 0x1fa7, 0x28ef, 0xf8b3, 0xd2f5, 0xeca5, 0x2160, 0x26fd, 0xf5d7, 0xd334,
|
||||
0xefa1, 0x22e5, 0x24ea, 0xf31b, 0xd3a9, 0xf29f, 0x2435, 0x22b6, 0xf07e, 0xd44e,
|
||||
0xf59b, 0x2551, 0x2067, 0xee08, 0xd527, 0xf88e, 0x2639, 0x1e00, 0xebb6, 0xd62d,
|
||||
0xfb77, 0x26eb, 0x1b85, 0xe98b, 0xd75f, 0xfe51, 0x276b, 0x18f9, 0xe78e, 0xd8b9,
|
||||
0x011a, 0x27b6, 0x1660, 0xe5bb, 0xda3a, 0x03cc, 0x27cf, 0x13bd, 0xe415, 0xdbdf,
|
||||
0x066a, 0x27b7, 0x1117, 0xe29e, 0xdda5, 0x08ec, 0x276e, 0x0e6d, 0xe154, 0xdf89,
|
||||
0x0b52, 0x26f6, 0x0bc7, 0xe039, 0xe185, 0x0d96, 0x2653, 0x0924, 0xdf4e, 0xe399,
|
||||
0x0fb9, 0x2584, 0x068b, 0xde93, 0xe5c0, 0x11b8, 0x248e, 0x03fd, 0xde08, 0xe7f8,
|
||||
0x1390, 0x2372, 0x0180, 0xddaa, 0xea3c, 0x1544, 0x2231, 0xff12, 0xdd7a, 0xec89,
|
||||
0x16cf, 0x20d0, 0xfcb9, 0xdd77, 0xeedb, 0x1831, 0x1f52, 0xfa77, 0xdd9f, 0xf132,
|
||||
0x1969, 0x1db7, 0xf850, 0xddf1, 0xf385, 0x1a75, 0x1c06, 0xf645, 0xde6b, 0xf5d7,
|
||||
0x1b5b, 0x1a3f, 0xf457, 0xdf0d, 0xf820, 0x1c13, 0x1867, 0xf288, 0xdfd2, 0xfa5f,
|
||||
0x1ca1, 0x167f, 0xf0db, 0xe0ba, 0xfc92, 0x1d06, 0x148b, 0xef50, 0xe1c1, 0xfeb5,
|
||||
0x1d43, 0x1290, 0xede9, 0xe2e6, 0x00c6, 0x1d58, 0x108e, 0xeca7, 0xe426, 0x02c4,
|
||||
0x1d45, 0x0e8a, 0xeb8a, 0xe57f, 0x04a9, 0x1d0e, 0x0c87, 0xea92, 0xe6ec, 0x0677,
|
||||
0x1cb2, 0x0a87, 0xe9be, 0xe86e, 0x082a, 0x1c34, 0x088b, 0xe912, 0xe9fe, 0x09c1,
|
||||
0x1b95, 0x069c, 0xe88c, 0xeb9c, 0x0b3a, 0x1ad9, 0x04b6, 0xe82a, 0xed43, 0x0c96,
|
||||
0x1a00, 0x02df, 0xe7eb, 0xeef3, 0x0dd0, 0x190d, 0x0116, 0xe7d0, 0xf0a8, 0x0eec,
|
||||
0x1804, 0xff61, 0xe7d8, 0xf25d, 0x0fe6, 0x16e3, 0xfdc0, 0xe800, 0xf412, 0x10bf,
|
||||
0x15b1, 0xfc36, 0xe848, 0xf5c5, 0x1176, 0x146e, 0xfac2, 0xe8ad, 0xf771, 0x120d,
|
||||
0x1320, 0xf969, 0xe92e, 0xf913, 0x1282, 0x11c4, 0xf828, 0xe9cb, 0xfaac, 0x12d8,
|
||||
0x1062, 0xf703, 0xea7e, 0xfc38, 0x130e, 0x0efa, 0xf5fb, 0xeb49, 0xfdb5, 0x1325,
|
||||
0x0d8e, 0xf50e, 0xec26, 0xff20, 0x131e, 0x0c21, 0xf43f, 0xed15, 0x007a, 0x12fa,
|
||||
0x0ab6, 0xf38d, 0xee15, 0x01be, 0x12bd, 0x094f, 0xf2f9, 0xef22, 0x02ef, 0x1265,
|
||||
0x07f0, 0xf283, 0xf037, 0x0408, 0x11f6, 0x0699, 0xf226, 0xf156, 0x050a, 0x1170,
|
||||
0x054b, 0xf1e8, 0xf27a, 0x05f4, 0x10d8, 0x040c, 0xf1c5, 0xf3a3, 0x06c2, 0x102c,
|
||||
0x02da, 0xf1bc, 0xf4cc, 0x0779, 0x0f71, 0x01b7, 0xf1cc, 0xf5f5, 0x0815, 0x0ea7,
|
||||
0x00a8, 0xf1f4, 0xf719, 0x0899, 0x0dd2, 0xffab, 0xf233, 0xf839, 0x0902, 0x0cf4,
|
||||
0xfec0, 0xf288, 0xf950, 0x0952, 0x0c0e, 0xfdec, 0xf2ee, 0xfa5d, 0x0989, 0x0b23,
|
||||
0xfd2d, 0xf368, 0xfb62, 0x09a7, 0x0a35, 0xfc85, 0xf3f1, 0xfc58, 0x09af, 0x0946,
|
||||
0xfbf2, 0xf488, 0xfd3f, 0x09a1, 0x0859, 0xfb77, 0xf52c, 0xfe17, 0x097d, 0x076f,
|
||||
0xfb14, 0xf5d8, 0xfede, 0x0945, 0x068a, 0xfac6, 0xf68d, 0xff93, 0x08fb, 0x05ad,
|
||||
0xfa8e, 0xf747, 0x0034, 0x08a1, 0x04da, 0xfa6f, 0xf805, 0x00c2, 0x0836, 0x0410,
|
||||
0xfa63, 0xf8c6, 0x013c, 0x07bf, 0x0354, 0xfa6c, 0xf985, 0x01a1, 0x073b, 0x02a4,
|
||||
0xfa8a, 0xfa43, 0x01f1, 0x06af, 0x0204, 0xfab9, 0xfafc, 0x022c, 0x0619, 0x0175,
|
||||
0xfafa, 0xfbae, 0x0252, 0x057f, 0x00f6, 0xfb4b, 0xfc5a, 0x0263, 0x04e0, 0x008b,
|
||||
0xfbaa, 0xfcfa, 0x0262, 0x0440, 0x0032, 0xfc16, 0xfd90, 0x024b, 0x03a0, 0xffec,
|
||||
0xfc8c, 0xfe19, 0x0225, 0x0301, 0xffb9, 0xfd0c, 0xfe93, 0x01ea, 0x0267, 0xff9c,
|
||||
0xfd95, 0xfefe, 0x01a0, 0x01d3, 0xff90, 0xfe22, 0xff5a, 0x0147, 0x0145, 0xff99,
|
||||
0xfeb3, 0xffa1, 0x00e0, 0x00c3, 0xffb6, 0xff46, 0xffd9, 0x006d, 0x004b, 0xffe5,
|
||||
0xffda, 0xfffc, 000000, 0xfffe, 000000, 0xffff, 000000, 0xffff, 0xffff, 000000,
|
||||
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
|
||||
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
|
||||
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
|
||||
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
|
||||
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
|
||||
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
|
||||
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
|
||||
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
|
||||
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
|
||||
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
|
||||
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
|
||||
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
|
||||
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
|
||||
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
|
||||
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
|
||||
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
|
||||
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
|
||||
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
|
||||
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
|
||||
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
|
||||
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
|
||||
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
|
||||
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
|
||||
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
|
||||
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
|
||||
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
|
||||
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
|
||||
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
|
||||
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
|
||||
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
|
||||
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
|
||||
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
|
||||
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
|
||||
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
|
||||
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
|
||||
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
|
||||
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
|
||||
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
|
||||
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
|
||||
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
|
||||
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
|
||||
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
|
||||
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
|
||||
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
|
||||
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
|
||||
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
|
||||
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
|
||||
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
|
||||
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
|
||||
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
|
||||
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
|
||||
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
|
||||
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
|
||||
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
|
||||
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
|
||||
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
|
||||
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
|
||||
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
|
||||
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
|
||||
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
|
||||
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
|
||||
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
|
||||
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
|
||||
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
|
||||
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
|
||||
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
|
||||
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
|
||||
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
|
||||
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
|
||||
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
|
||||
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
|
||||
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
|
||||
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
|
||||
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
|
||||
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
|
||||
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
|
||||
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
|
||||
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
|
||||
000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000,
|
||||
000000 };
|
55
utils/iaxclient/lib/libiax2/src/busy.h
Normal file
55
utils/iaxclient/lib/libiax2/src/busy.h
Normal file
|
@ -0,0 +1,55 @@
|
|||
/* busy.h: Generated from frequencies 480 and 620
|
||||
by gensound. 400 samples */
|
||||
static short busy[400] = {
|
||||
0, 13697, 24766, 31109, 31585, 26222, 16198, 3569,
|
||||
-9162, -19575, -25812, -26935, -23069, -15322, -5493, 4339,
|
||||
12277, 16985, 17934, 15440, 10519, 4585, -908, -4827,
|
||||
-6592, -6269, -4489, -2220, -467, 30, -983, -3203,
|
||||
-5839, -7844, -8215, -6301, -2035, 3975, 10543, 16141,
|
||||
19260, 18787, 14322, 6338, -3845, -14296, -22858, -27611,
|
||||
-27309, -21691, -11585, 1213, 14285, 25068, 31388, 31915,
|
||||
26457, 16010, 2568, -11282, -22885, -30054, -31509, -27120,
|
||||
-17908, -5805, 6760, 17379, 24147, 26028, 23020, 16094,
|
||||
6931, -2478, -10279, -15136, -16474, -14538, -10253, -4949,
|
||||
0, 3515, 5052, 4688, 3045, 1069, -268, -272,
|
||||
1269, 3996, 7067, 9381, 9889, 7910, 3365, -3123,
|
||||
-10320, -16622, -20424, -20510, -16384, -8448, 2006, 13026,
|
||||
22383, 28040, 28613, 23696, 13996, 1232, -12193, -23670,
|
||||
-30918, -32459, -27935, -18190, -5103, 8795, 20838, 28764,
|
||||
31164, 27753, 19395, 7893, -4412, -15136, -22342, -24909,
|
||||
-22717, -16609, -8143, 780, 8361, 13272, 14909, 13455,
|
||||
9758, 5067, 678, -2387, -3624, -3133, -1538, 224,
|
||||
1209, 751, -1315, -4580, -8145, -10848, -11585, -9628,
|
||||
-4878, 2038, 9844, 16867, 21403, 22124, 18429, 10638,
|
||||
0, -11524, -21643, -28211, -29702, -25561, -16364, -3737,
|
||||
9946, 22044, 30180, 32733, 29182, 20210, 7573, -6269,
|
||||
-18655, -27259, -30558, -28117, -20645, -9807, 2148, 12878,
|
||||
20426, 23599, 22173, 16865, 9117, 731, -6552, -11426,
|
||||
-13269, -12216, -9050, -4941, -1118, 1460, 2335, 1635,
|
||||
0, -1635, -2335, -1460, 1118, 4941, 9050, 12216,
|
||||
13269, 11426, 6552, -731, -9117, -16865, -22173, -23599,
|
||||
-20426, -12878, -2148, 9807, 20645, 28117, 30558, 27259,
|
||||
18655, 6269, -7573, -20210, -29182, -32733, -30180, -22044,
|
||||
-9946, 3737, 16364, 25561, 29702, 28211, 21643, 11524,
|
||||
0, -10638, -18429, -22124, -21403, -16867, -9844, -2038,
|
||||
4878, 9628, 11585, 10848, 8145, 4580, 1315, -751,
|
||||
-1209, -224, 1538, 3133, 3624, 2387, -678, -5067,
|
||||
-9758, -13455, -14909, -13272, -8361, -780, 8143, 16609,
|
||||
22717, 24909, 22342, 15136, 4412, -7893, -19395, -27753,
|
||||
-31164, -28764, -20838, -8795, 5103, 18190, 27935, 32459,
|
||||
30918, 23670, 12193, -1232, -13996, -23696, -28613, -28040,
|
||||
-22383, -13026, -2006, 8448, 16384, 20510, 20424, 16622,
|
||||
10320, 3123, -3365, -7910, -9889, -9381, -7067, -3996,
|
||||
-1269, 272, 268, -1069, -3045, -4688, -5052, -3515,
|
||||
0, 4949, 10253, 14538, 16474, 15136, 10279, 2478,
|
||||
-6931, -16094, -23020, -26028, -24147, -17379, -6760, 5805,
|
||||
17908, 27120, 31509, 30054, 22885, 11282, -2568, -16010,
|
||||
-26457, -31915, -31388, -25068, -14285, -1213, 11585, 21691,
|
||||
27309, 27611, 22858, 14296, 3845, -6338, -14322, -18787,
|
||||
-19260, -16141, -10543, -3975, 2035, 6301, 8215, 7844,
|
||||
5839, 3203, 983, -30, 467, 2220, 4489, 6269,
|
||||
6592, 4827, 908, -4585, -10519, -15440, -17934, -16985,
|
||||
-12277, -4339, 5493, 15322, 23069, 26935, 25812, 19575,
|
||||
9162, -3569, -16198, -26222, -31585, -31109, -24766, -13697,
|
||||
|
||||
};
|
105
utils/iaxclient/lib/libiax2/src/dialtone.h
Normal file
105
utils/iaxclient/lib/libiax2/src/dialtone.h
Normal file
|
@ -0,0 +1,105 @@
|
|||
/* dialtone.h: Generated from frequencies 350 and 440
|
||||
by gensound. 800 samples */
|
||||
static short dialtone[800] = {
|
||||
0, 9997, 19004, 26133, 30692, 32251, 30690, 26206,
|
||||
19286, 10657, 1206, -8116, -16396, -22848, -26895, -28221,
|
||||
-26797, -22878, -16960, -9723, -1954, 5545, 12044, 16954,
|
||||
19887, 20687, 19434, 16420, 12107, 7061, 1881, -2866,
|
||||
-6721, -9365, -10657, -10634, -9491, -7547, -5190, -2822,
|
||||
-801, 607, 1263, 1168, 454, -633, -1784, -2669,
|
||||
-2993, -2548, -1247, 855, 3558, 6538, 9388, 11665,
|
||||
12955, 12933, 11408, 8370, 3996, -1349, -7152, -12797,
|
||||
-17635, -21060, -22583, -21895, -18914, -13807, -6985, 934,
|
||||
9180, 16913, 23309, 27654, 29422, 28342, 24429, 17998,
|
||||
9630, 123, -9589, -18538, -25813, -30667, -32588, -31360,
|
||||
-27088, -20185, -11332, -1411, 8594, 17694, 24997, 29805,
|
||||
31675, 30473, 26374, 19844, 11585, 2455, -6618, -14745,
|
||||
-21156, -25284, -26815, -25713, -22213, -16785, -10073, -2824,
|
||||
4203, 10318, 14969, 17794, 18653, 17628, 14998, 11197,
|
||||
6753, 2217, -1899, -5189, -7386, -8388, -8261, -7212,
|
||||
-5555, -3657, -1881, -536, 169, 157, -515, -1664,
|
||||
-3009, -4217, -4954, -4940, -3996, -2080, 697, 4081,
|
||||
7689, 11059, 13710, 15199, 15187, 13489, 10114, 5272,
|
||||
-630, -7031, -13263, -18632, -22491, -24320, -23794, -20823,
|
||||
-15582, -8498, -218, 8457, 16651, 23507, 28276, 30407,
|
||||
29606, 25876, 19524, 11134, 1511, -8401, -17616, -25208,
|
||||
-30406, -32682, -31800, -27845, -21215, -12576, -2796, 7150,
|
||||
16278, 23700, 28713, 30868, 30015, 26312, 20199, 12351,
|
||||
3598, -5164, -13071, -19378, -23531, -25223, -24413, -21318,
|
||||
-16384, -10218, -3526, 2980, 8655, 12985, 15642, 16505,
|
||||
15661, 13381, 10073, 6228, 2348, -1110, -3796, -5495,
|
||||
-6152, -5863, -4853, -3434, -1954, -744, -62, -60,
|
||||
-757, -2037, -3664, -5317, -6637, -7283, -6985, -5590,
|
||||
-3096, 334, 4390, 8631, 12544, 15605, 17339, 17393,
|
||||
15582, 11928, 6672, 258, -6705, -13506, -19403, -23711,
|
||||
-25879, -25558, -22653, -17341, -10061, -1480, 7570, 16185,
|
||||
23475, 28661, 31164, 30670, 27167, 20951, 12603, 2930,
|
||||
-7116, -16540, -24401, -29915, -32533, -32003, -28391, -22075,
|
||||
-13704, -4128, 5690, 14781, 22262, 27432, 29838, 29319,
|
||||
26014, 20339, 12940, 4614, -3777, -11401, -17540, -21660,
|
||||
-23463, -22908, -20199, -15755, -10150, -4044, 1898, 7079,
|
||||
11030, 13459, 14268, 13555, 11585, 8745, 5487, 2268,
|
||||
-511, -2559, -3716, -3975, -3468, -2440, -1206, -101,
|
||||
578, 618, -78, -1470, -3382, -5524, -7531, -9018,
|
||||
-9630, -9103, -7308, -4280, -226, 4483, 9357, 13829,
|
||||
17329, 19352, 19524, 17659, 13788, 8177, 1302, -6184,
|
||||
-13528, -19945, -24710, -27240, -27167, -24381, -19058, -11646,
|
||||
-2830, 6539, 15528, 23219, 28806, 31685, 31520, 28282,
|
||||
22254, 14010, 4355, -5759, -15331, -23411, -29203, -32144,
|
||||
-31966, -28714, -22748, -14695, -5384, 4241, 13228, 20707,
|
||||
25981, 28600, 28391, 25479, 20256, 13337, 5482, -2482,
|
||||
-9761, -15668, -19694, -21556, -21215, -18865, -14902, -9864,
|
||||
-4366, 975, 5614, 9130, 11270, 11967, 11332, 9628,
|
||||
7223, 4536, 1976, -113, -1495, -2071, -1882, -1102,
|
||||
0, 1102, 1882, 2071, 1495, 113, -1976, -4536,
|
||||
-7223, -9628, -11332, -11967, -11270, -9130, -5614, -975,
|
||||
4366, 9864, 14902, 18865, 21215, 21556, 19694, 15668,
|
||||
9761, 2482, -5482, -13337, -20256, -25479, -28391, -28600,
|
||||
-25981, -20707, -13228, -4241, 5384, 14695, 22748, 28714,
|
||||
31966, 32144, 29203, 23411, 15331, 5759, -4355, -14010,
|
||||
-22254, -28282, -31520, -31685, -28806, -23219, -15528, -6539,
|
||||
2830, 11646, 19058, 24381, 27167, 27240, 24710, 19945,
|
||||
13528, 6184, -1302, -8177, -13788, -17659, -19524, -19352,
|
||||
-17329, -13829, -9357, -4483, 226, 4280, 7308, 9103,
|
||||
9630, 9018, 7531, 5524, 3382, 1470, 78, -618,
|
||||
-578, 101, 1206, 2440, 3468, 3975, 3716, 2559,
|
||||
511, -2268, -5487, -8745, -11585, -13555, -14268, -13459,
|
||||
-11030, -7079, -1898, 4044, 10150, 15755, 20199, 22908,
|
||||
23463, 21660, 17540, 11401, 3777, -4614, -12940, -20339,
|
||||
-26014, -29319, -29838, -27432, -22262, -14781, -5690, 4128,
|
||||
13704, 22075, 28391, 32003, 32533, 29915, 24401, 16540,
|
||||
7116, -2930, -12603, -20951, -27167, -30670, -31164, -28661,
|
||||
-23475, -16185, -7570, 1480, 10061, 17341, 22653, 25558,
|
||||
25879, 23711, 19403, 13506, 6705, -258, -6672, -11928,
|
||||
-15582, -17393, -17339, -15605, -12544, -8631, -4390, -334,
|
||||
3096, 5590, 6985, 7283, 6637, 5317, 3664, 2037,
|
||||
757, 60, 62, 744, 1954, 3434, 4853, 5863,
|
||||
6152, 5495, 3796, 1110, -2348, -6228, -10073, -13381,
|
||||
-15661, -16505, -15642, -12985, -8655, -2980, 3526, 10218,
|
||||
16384, 21318, 24413, 25223, 23531, 19378, 13071, 5164,
|
||||
-3598, -12351, -20199, -26312, -30015, -30868, -28713, -23700,
|
||||
-16278, -7150, 2796, 12576, 21215, 27845, 31800, 32682,
|
||||
30406, 25208, 17616, 8401, -1511, -11134, -19524, -25876,
|
||||
-29606, -30407, -28276, -23507, -16651, -8457, 218, 8498,
|
||||
15582, 20823, 23794, 24320, 22491, 18632, 13263, 7031,
|
||||
630, -5272, -10114, -13489, -15187, -15199, -13710, -11059,
|
||||
-7689, -4081, -697, 2080, 3996, 4940, 4954, 4217,
|
||||
3009, 1664, 515, -157, -169, 536, 1881, 3657,
|
||||
5555, 7212, 8261, 8388, 7386, 5189, 1899, -2217,
|
||||
-6753, -11197, -14998, -17628, -18653, -17794, -14969, -10318,
|
||||
-4203, 2824, 10073, 16785, 22213, 25713, 26815, 25284,
|
||||
21156, 14745, 6618, -2455, -11585, -19844, -26374, -30473,
|
||||
-31675, -29805, -24997, -17694, -8594, 1411, 11332, 20185,
|
||||
27088, 31360, 32588, 30667, 25813, 18538, 9589, -123,
|
||||
-9630, -17998, -24429, -28342, -29422, -27654, -23309, -16913,
|
||||
-9180, -934, 6985, 13807, 18914, 21895, 22583, 21060,
|
||||
17635, 12797, 7152, 1349, -3996, -8370, -11408, -12933,
|
||||
-12955, -11665, -9388, -6538, -3558, -855, 1247, 2548,
|
||||
2993, 2669, 1784, 633, -454, -1168, -1263, -607,
|
||||
801, 2822, 5190, 7547, 9491, 10634, 10657, 9365,
|
||||
6721, 2866, -1881, -7061, -12107, -16420, -19434, -20687,
|
||||
-19887, -16954, -12044, -5545, 1954, 9723, 16960, 22878,
|
||||
26797, 28221, 26895, 22848, 16396, 8116, -1206, -10657,
|
||||
-19286, -26206, -30690, -32251, -30692, -26133, -19004, -9997,
|
||||
|
||||
};
|
142
utils/iaxclient/lib/libiax2/src/frame.h
Normal file
142
utils/iaxclient/lib/libiax2/src/frame.h
Normal file
|
@ -0,0 +1,142 @@
|
|||
/*
|
||||
* libiax: An implementation of the Inter-Asterisk eXchange protocol
|
||||
*
|
||||
* Asterisk internal frame definitions.
|
||||
*
|
||||
* Copyright (C) 1999, Mark Spencer
|
||||
*
|
||||
* Mark Spencer <markster@linux-support.net>
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU Lesser General Public License. Other components of
|
||||
* Asterisk are distributed under The GNU General Public License
|
||||
* only.
|
||||
*/
|
||||
|
||||
#ifndef _LIBIAX_FRAME_H
|
||||
#define _LIBIAX_FRAME_H
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Frame types */
|
||||
#define AST_FRAME_DTMF 1 /* A DTMF digit, subclass is the digit */
|
||||
#define AST_FRAME_VOICE 2 /* Voice data, subclass is AST_FORMAT_* */
|
||||
#define AST_FRAME_VIDEO 3 /* Video frame, maybe?? :) */
|
||||
#define AST_FRAME_CONTROL 4 /* A control frame, subclass is AST_CONTROL_* */
|
||||
#define AST_FRAME_NULL 5 /* An empty, useless frame */
|
||||
#define AST_FRAME_IAX 6 /* Inter Aterisk Exchange private frame type */
|
||||
#define AST_FRAME_TEXT 7 /* Text messages */
|
||||
#define AST_FRAME_IMAGE 8 /* Image Frames */
|
||||
#define AST_FRAME_HTML 9 /* HTML Frames */
|
||||
#define AST_FRAME_CNG 10 /* Comfort Noise frame (subclass is level of CNG in -dBov) */
|
||||
|
||||
/* HTML subclasses */
|
||||
#define AST_HTML_URL 1 /* Sending a URL */
|
||||
#define AST_HTML_DATA 2 /* Data frame */
|
||||
#define AST_HTML_BEGIN 4 /* Beginning frame */
|
||||
#define AST_HTML_END 8 /* End frame */
|
||||
#define AST_HTML_LDCOMPLETE 16 /* Load is complete */
|
||||
#define AST_HTML_NOSUPPORT 17 /* Peer is unable to support HTML */
|
||||
#define AST_HTML_LINKURL 18 /* Send URL and track */
|
||||
#define AST_HTML_UNLINK 19 /* Request no more linkage */
|
||||
#define AST_HTML_LINKREJECT 20 /* Reject LINKURL */
|
||||
|
||||
/* Data formats for capabilities and frames alike */
|
||||
/*! G.723.1 compression */
|
||||
#define AST_FORMAT_G723_1 (1 << 0)
|
||||
/*! GSM compression */
|
||||
#define AST_FORMAT_GSM (1 << 1)
|
||||
/*! Raw mu-law data (G.711) */
|
||||
#define AST_FORMAT_ULAW (1 << 2)
|
||||
/*! Raw A-law data (G.711) */
|
||||
#define AST_FORMAT_ALAW (1 << 3)
|
||||
/*! ADPCM (G.726, 32kbps) */
|
||||
#define AST_FORMAT_G726 (1 << 4)
|
||||
/*! ADPCM (IMA) */
|
||||
#define AST_FORMAT_ADPCM (1 << 5)
|
||||
/*! Raw 16-bit Signed Linear (8000 Hz) PCM */
|
||||
#define AST_FORMAT_SLINEAR (1 << 6)
|
||||
/*! LPC10, 180 samples/frame */
|
||||
#define AST_FORMAT_LPC10 (1 << 7)
|
||||
/*! G.729A audio */
|
||||
#define AST_FORMAT_G729A (1 << 8)
|
||||
/*! SpeeX Free Compression */
|
||||
#define AST_FORMAT_SPEEX (1 << 9)
|
||||
/*! iLBC Free Compression */
|
||||
#define AST_FORMAT_ILBC (1 << 10)
|
||||
/*! Maximum audio format */
|
||||
#define AST_FORMAT_MAX_AUDIO (1 << 15)
|
||||
/*! JPEG Images */
|
||||
#define AST_FORMAT_JPEG (1 << 16)
|
||||
/*! PNG Images */
|
||||
#define AST_FORMAT_PNG (1 << 17)
|
||||
/*! H.261 Video */
|
||||
#define AST_FORMAT_H261 (1 << 18)
|
||||
/*! H.263 Video */
|
||||
#define AST_FORMAT_H263 (1 << 19)
|
||||
/*! H.263+ Video */
|
||||
#define AST_FORMAT_H263p (1 << 20)
|
||||
/*! H.264 Video*/
|
||||
#define AST_FORMAT_H264 (1 << 21)
|
||||
/*! MPEG4 Video*/
|
||||
#define AST_FORMAT_MPEG4 (1 << 22)
|
||||
/*! Theora Video */
|
||||
#define AST_FORMAT_THEORA (1 << 24)
|
||||
/*! Max one */
|
||||
#define AST_FORMAT_MAX_VIDEO (1 << 24)
|
||||
|
||||
/* Control frame types */
|
||||
#define AST_CONTROL_HANGUP 1 /* Other end has hungup */
|
||||
#define AST_CONTROL_RING 2 /* Local ring */
|
||||
#define AST_CONTROL_RINGING 3 /* Remote end is ringing */
|
||||
#define AST_CONTROL_ANSWER 4 /* Remote end has answered */
|
||||
#define AST_CONTROL_BUSY 5 /* Remote end is busy */
|
||||
#define AST_CONTROL_TAKEOFFHOOK 6 /* Make it go off hook */
|
||||
#define AST_CONTROL_OFFHOOK 7 /* Line is off hook */
|
||||
#define AST_CONTROL_CONGESTION 8 /* Congestion (circuits busy) */
|
||||
#define AST_CONTROL_FLASH 9 /* Flash hook */
|
||||
#define AST_CONTROL_WINK 10 /* Wink */
|
||||
#define AST_CONTROL_OPTION 11 /* Set an option */
|
||||
|
||||
#define AST_FRIENDLY_OFFSET 64 /* Reserved header space */
|
||||
|
||||
struct ast_frame {
|
||||
/*! Kind of frame */
|
||||
int frametype;
|
||||
/*! Subclass, frame dependent */
|
||||
int subclass;
|
||||
/*! Length of data */
|
||||
int datalen;
|
||||
/*! Number of 8khz samples in this frame */
|
||||
int samples;
|
||||
/*! Was the data malloc'd? i.e. should we free it when we discard the f
|
||||
rame? */
|
||||
int mallocd;
|
||||
/*! How far into "data" the data really starts */
|
||||
int offset;
|
||||
/*! Optional source of frame for debugging */
|
||||
char *src;
|
||||
/*! Pointer to actual data */
|
||||
void *data;
|
||||
/*! Next/Prev for linking stand alone frames */
|
||||
struct ast_frame *prev;
|
||||
/*! Next/Prev for linking stand alone frames */
|
||||
struct ast_frame *next;
|
||||
/* Unused except
|
||||
if debugging is turned on, but left
|
||||
in the struct
|
||||
so that it can be turned on without
|
||||
requiring a r
|
||||
ecompile of the whole thing */
|
||||
};
|
||||
|
||||
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
259
utils/iaxclient/lib/libiax2/src/iax-client.h
Normal file
259
utils/iaxclient/lib/libiax2/src/iax-client.h
Normal file
|
@ -0,0 +1,259 @@
|
|||
/*
|
||||
* Asterisk -- A telephony toolkit for Linux.
|
||||
*
|
||||
* Implementation of Inter-Asterisk eXchange
|
||||
*
|
||||
* Copyright (C) 1999, Mark Spencer
|
||||
*
|
||||
* Mark Spencer <markster@linux-support.net>
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU Lesser General Public License (LGPL)
|
||||
*/
|
||||
|
||||
#ifndef _ASTERISK_IAX_CLIENT_H
|
||||
#define _ASTERISK_IAX_CLIENT_H
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
/* disable zero-sized array in struct/union warning */
|
||||
#pragma warning(disable:4200)
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
#define socklen_t int
|
||||
#endif
|
||||
|
||||
#include "frame.h"
|
||||
#include "iax2.h"
|
||||
#include "iax2-parser.h"
|
||||
|
||||
#define MAXSTRLEN 80
|
||||
|
||||
#define IAX_AUTHMETHOD_PLAINTEXT IAX_AUTH_PLAINTEXT
|
||||
#define IAX_AUTHMETHOD_MD5 IAX_AUTH_MD5
|
||||
|
||||
extern char iax_errstr[];
|
||||
|
||||
struct iax_session;
|
||||
|
||||
|
||||
#define IAX_EVENT_CONNECT 0 /* Connect a new call */
|
||||
#define IAX_EVENT_ACCEPT 1 /* Accept a call */
|
||||
#define IAX_EVENT_HANGUP 2 /* Hang up a call */
|
||||
#define IAX_EVENT_REJECT 3 /* Rejected call */
|
||||
#define IAX_EVENT_VOICE 4 /* Voice Data */
|
||||
#define IAX_EVENT_DTMF 5 /* A DTMF Tone */
|
||||
#define IAX_EVENT_TIMEOUT 6 /* Connection timeout... session
|
||||
will be a pointer to free()'d
|
||||
memory! */
|
||||
#define IAX_EVENT_LAGRQ 7 /* Lag request -- Internal use only */
|
||||
#define IAX_EVENT_LAGRP 8 /* Lag Measurement. See event.lag */
|
||||
#define IAX_EVENT_RINGA 9 /* Announce we/they are ringing */
|
||||
#define IAX_EVENT_PING 10 /* Ping -- internal use only */
|
||||
#define IAX_EVENT_PONG 11 /* Pong -- internal use only */
|
||||
#define IAX_EVENT_BUSY 12 /* Report a line busy */
|
||||
#define IAX_EVENT_ANSWER 13 /* Answer the line */
|
||||
|
||||
#define IAX_EVENT_IMAGE 14 /* Send/Receive an image */
|
||||
#define IAX_EVENT_AUTHRQ 15 /* Authentication request */
|
||||
#define IAX_EVENT_AUTHRP 16 /* Authentication reply */
|
||||
|
||||
#define IAX_EVENT_REGREQ 17 /* Registration request */
|
||||
#define IAX_EVENT_REGACK 18 /* Registration reply */
|
||||
#define IAX_EVENT_URL 19 /* URL received */
|
||||
#define IAX_EVENT_LDCOMPLETE 20 /* URL loading complete */
|
||||
|
||||
#define IAX_EVENT_TRANSFER 21 /* Transfer has taken place */
|
||||
|
||||
#define IAX_EVENT_DPREQ 22 /* Dialplan request */
|
||||
#define IAX_EVENT_DPREP 23 /* Dialplan reply */
|
||||
#define IAX_EVENT_DIAL 24 /* Dial on a TBD call */
|
||||
|
||||
#define IAX_EVENT_QUELCH 25 /* Quelch Audio */
|
||||
#define IAX_EVENT_UNQUELCH 26 /* Unquelch Audio */
|
||||
|
||||
#define IAX_EVENT_UNLINK 27 /* Unlink */
|
||||
#define IAX_EVENT_LINKREJECT 28 /* Link Rejection */
|
||||
#define IAX_EVENT_TEXT 29 /* Text Frame :-) */
|
||||
#define IAX_EVENT_REGREJ 30 /* Registration reply */
|
||||
#define IAX_EVENT_LINKURL 31 /* Unlink */
|
||||
#define IAX_EVENT_CNG 32 /* Comfort-noise (almost silence) */
|
||||
#define IAX_EVENT_POKE 33
|
||||
#define IAX_EVENT_VIDEO 34 /* Send/receive video */
|
||||
|
||||
|
||||
/* moved from iax.c to support attended transfer */
|
||||
#define IAX_EVENT_REREQUEST 999
|
||||
#define IAX_EVENT_TXREPLY 1000
|
||||
#define IAX_EVENT_TXREJECT 1001
|
||||
#define IAX_EVENT_TXACCEPT 1002
|
||||
#define IAX_EVENT_TXREADY 1003
|
||||
|
||||
/*
|
||||
* Null event. We use it to notify back the caller that a frame has been
|
||||
* received and is queued for delivery
|
||||
* Applciations should simply ignore it
|
||||
*/
|
||||
#define IAX_EVENT_NULL 65535
|
||||
|
||||
#define IAX_SCHEDULE_FUZZ 0 /* ms of fuzz to drop */
|
||||
|
||||
#if defined(WIN32) || defined(_WIN32_WCE)
|
||||
#if defined(_MSC_VER)
|
||||
typedef int (__stdcall *iax_sendto_t)(SOCKET, const void *, size_t, int,
|
||||
const struct sockaddr *, socklen_t);
|
||||
typedef int (__stdcall *iax_recvfrom_t)(SOCKET, void *, size_t, int,
|
||||
struct sockaddr *, socklen_t *);
|
||||
#else
|
||||
typedef int PASCAL (*iax_sendto_t)(SOCKET, const char *, int, int,
|
||||
const struct sockaddr *, int);
|
||||
typedef int PASCAL (*iax_recvfrom_t)(SOCKET, char *, int, int,
|
||||
struct sockaddr *, int *);
|
||||
#endif
|
||||
#else
|
||||
typedef int (*iax_sendto_t)(int, const void *, size_t, int,
|
||||
const struct sockaddr *, socklen_t);
|
||||
typedef int (*iax_recvfrom_t)(int, void *, size_t, int,
|
||||
struct sockaddr *, socklen_t *);
|
||||
#endif
|
||||
|
||||
struct iax_event {
|
||||
int etype; /* Type of event */
|
||||
int subclass; /* Subclass data (event specific) */
|
||||
unsigned int ts; /* Timestamp */
|
||||
struct iax_session *session; /* Applicable session */
|
||||
int datalen; /* Length of raw data */
|
||||
struct iax_ies ies; /* IE's for IAX2 frames */
|
||||
unsigned char data[0]; /* Raw data if applicable */
|
||||
};
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/* All functions return 0 on success and -1 on failure unless otherwise
|
||||
specified */
|
||||
|
||||
/* Called to initialize IAX structures and sockets. Returns actual
|
||||
portnumber (which it will try preferred portno first, but if not
|
||||
take what it can get */
|
||||
extern int iax_init(int preferredportno);
|
||||
|
||||
/* Get filedescriptor for IAX to use with select or gtk_input_add */
|
||||
extern int iax_get_fd(void);
|
||||
|
||||
/* Find out how many milliseconds until the next scheduled event */
|
||||
extern int iax_time_to_next_event(void);
|
||||
|
||||
/* Generate a new IAX session */
|
||||
extern struct iax_session *iax_session_new(void);
|
||||
|
||||
/* Return exactly one iax event (if there is one pending). If blocking is
|
||||
non-zero, IAX will block until some event is received */
|
||||
extern struct iax_event *iax_get_event(int blocking);
|
||||
|
||||
|
||||
extern int iax_auth_reply(struct iax_session *session, char *password,
|
||||
char *challenge, int methods);
|
||||
|
||||
/* Free an event */
|
||||
extern void iax_event_free(struct iax_event *event);
|
||||
|
||||
struct sockaddr_in;
|
||||
|
||||
/* Front ends for sending events */
|
||||
extern int iax_send_dtmf(struct iax_session *session, char digit);
|
||||
extern int iax_send_voice(struct iax_session *session, int format, unsigned char *data, int datalen, int samples);
|
||||
extern int iax_send_cng(struct iax_session *session, int level, unsigned char *data, int datalen);
|
||||
extern int iax_send_image(struct iax_session *session, int format, unsigned char *data, int datalen);
|
||||
extern int iax_send_url(struct iax_session *session, const char *url, int link);
|
||||
extern int iax_send_text(struct iax_session *session, const char *text);
|
||||
extern int iax_send_ping(struct iax_session *session);
|
||||
extern int iax_load_complete(struct iax_session *session);
|
||||
extern int iax_reject(struct iax_session *session, char *reason);
|
||||
extern int iax_busy(struct iax_session *session);
|
||||
extern int iax_congestion(struct iax_session *session);
|
||||
extern int iax_hangup(struct iax_session *session, char *byemsg);
|
||||
extern int iax_call(struct iax_session *session, const char *cidnum, const char *cidname, const char *ich, const char *lang, int wait, int format, int capability);
|
||||
extern int iax_accept(struct iax_session *session, int format);
|
||||
extern int iax_answer(struct iax_session *session);
|
||||
extern int iax_sendurl(struct iax_session *session, char *url);
|
||||
extern int iax_send_unlink(struct iax_session *session);
|
||||
extern int iax_send_link_reject(struct iax_session *session);
|
||||
extern int iax_ring_announce(struct iax_session *session);
|
||||
extern struct sockaddr_in iax_get_peer_addr(struct iax_session *session);
|
||||
extern int iax_register(struct iax_session *session, const char *hostname, const char *peer, const char *secret, int refresh);
|
||||
extern int iax_unregister(struct iax_session *session, const char *hostname, const char *peer, const char *secret, const char *reason);
|
||||
extern int iax_lag_request(struct iax_session *session);
|
||||
extern int iax_dial(struct iax_session *session, char *number); /* Dial on a TBD call */
|
||||
extern int iax_dialplan_request(struct iax_session *session, char *number); /* Request dialplan status for number */
|
||||
extern int iax_quelch(struct iax_session *session);
|
||||
extern int iax_unquelch(struct iax_session * session);
|
||||
extern int iax_transfer(struct iax_session *session, const char *number);
|
||||
extern int iax_quelch_moh(struct iax_session *session, int MOH);
|
||||
extern int iax_send_video(struct iax_session *session, int format, unsigned char *data, int datalen, int fullframe);
|
||||
extern int iax_send_video_trunk(struct iax_session *session, int format, char *data, int datalen, int fullframe, int ntrunk);
|
||||
|
||||
extern void iax_destroy(struct iax_session * session);
|
||||
|
||||
extern void iax_enable_debug(void);
|
||||
extern void iax_disable_debug(void);
|
||||
|
||||
extern struct timeval iax_tvnow(void);
|
||||
|
||||
/* For attended transfer, application create a new session,
|
||||
* make a call on the new session.
|
||||
* On answer of the new session, call iax_setup_transfer and wait for
|
||||
* IAX_EVENT_TXREADY when both sides are completed succefully or
|
||||
* IAX_EVENT_TXREJECT for either side.
|
||||
* If there are music on hold the it will be stopped by this library.
|
||||
*/
|
||||
extern int iax_setup_transfer(struct iax_session *s0, struct iax_session *s1);
|
||||
|
||||
struct iax_netstat {
|
||||
int jitter;
|
||||
int losspct;
|
||||
int losscnt;
|
||||
int packets;
|
||||
int delay;
|
||||
int dropped;
|
||||
int ooo;
|
||||
};
|
||||
/* fills in rtt, and an iax_netstat structure for each of local/remote directions of call */
|
||||
extern int iax_get_netstats(struct iax_session *s, int *rtt, struct iax_netstat *local, struct iax_netstat *remote);
|
||||
|
||||
|
||||
extern void iax_set_private(struct iax_session *s, void *pvt);
|
||||
extern void *iax_get_private(struct iax_session *s);
|
||||
extern void iax_set_sendto(struct iax_session *s, iax_sendto_t sendto);
|
||||
|
||||
/* to use application networking instead of internal, set call this instead of iax_init,
|
||||
* and pass in sendto and recvfrom replacements. blocking reads may not be implemented */
|
||||
extern void iax_set_networking(iax_sendto_t st, iax_recvfrom_t rf);
|
||||
|
||||
/* destroy an iax session */
|
||||
extern void iax_session_destroy(struct iax_session **session);
|
||||
|
||||
/* To control use of jitter buffer for video event */
|
||||
int iax_video_bypass_jitter(struct iax_session*, int );
|
||||
|
||||
/* Handle externally received frames */
|
||||
struct iax_event *iax_net_process(unsigned char *buf, int len, struct sockaddr_in *sin);
|
||||
extern unsigned int iax_session_get_capability(struct iax_session *s);
|
||||
extern char iax_pref_codec_add(struct iax_session *session, unsigned int format);
|
||||
extern void iax_pref_codec_del(struct iax_session *session, unsigned int format);
|
||||
extern int iax_pref_codec_get(struct iax_session *session, unsigned int *array, int len);
|
||||
|
||||
/* Fine tune jitterbuffer */
|
||||
extern void iax_set_jb_target_extra( long value );
|
||||
|
||||
/* Portable 'decent' random number generation */
|
||||
extern void iax_seed_random(void);
|
||||
extern int iax_random(void);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _ASTERISK_IAX_CLIENT_H */
|
3517
utils/iaxclient/lib/libiax2/src/iax.c
Normal file
3517
utils/iaxclient/lib/libiax2/src/iax.c
Normal file
File diff suppressed because it is too large
Load diff
86
utils/iaxclient/lib/libiax2/src/iax.h
Normal file
86
utils/iaxclient/lib/libiax2/src/iax.h
Normal file
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
* libIAX
|
||||
*
|
||||
* Implementation of Inter-IAXerisk eXchange
|
||||
*
|
||||
* Copyright (C) 1999, Mark Spencer
|
||||
*
|
||||
* Mark Spencer <markster@linux-support.net>
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU Lesser (Library) General Public License
|
||||
*/
|
||||
|
||||
#ifndef _IAX_H
|
||||
#define _IAX_H
|
||||
|
||||
/* Max version of IAX protocol we support */
|
||||
#define IAX_PROTO_VERSION 1
|
||||
|
||||
#define IAX_MAX_CALLS 32768
|
||||
|
||||
#define IAX_FLAG_FULL 0x8000
|
||||
|
||||
#define IAX_FLAG_SC_LOG 0x80
|
||||
|
||||
#define IAX_MAX_SHIFT 0x1F
|
||||
|
||||
/* Maximum size of an IAX frame (max size of UDP frame) */
|
||||
#define IAX_MAX_BUF_SIZE 65536
|
||||
|
||||
/* Subclass for IAX_FRAME_IAX */
|
||||
#define IAX_COMMAND_NEW 1
|
||||
#define IAX_COMMAND_PING 2
|
||||
#define IAX_COMMAND_PONG 3
|
||||
#define IAX_COMMAND_ACK 4
|
||||
#define IAX_COMMAND_HANGUP 5
|
||||
#define IAX_COMMAND_REJECT 6
|
||||
#define IAX_COMMAND_ACCEPT 7
|
||||
#define IAX_COMMAND_AUTHREQ 8
|
||||
#define IAX_COMMAND_AUTHREP 9
|
||||
#define IAX_COMMAND_INVAL 10
|
||||
#define IAX_COMMAND_LAGRQ 11
|
||||
#define IAX_COMMAND_LAGRP 12
|
||||
#define IAX_COMMAND_REGREQ 13 /* Registration request */
|
||||
#define IAX_COMMAND_REGAUTH 14 /* Registration authentication required */
|
||||
#define IAX_COMMAND_REGACK 15 /* Registration accepted */
|
||||
#define IAX_COMMAND_REGREJ 16 /* Registration rejected */
|
||||
#define IAX_COMMAND_REGREL 17 /* Force release of registration */
|
||||
#define IAX_COMMAND_VNAK 18 /* If we receive voice before valid first voice frame, send this */
|
||||
#define IAX_COMMAND_DPREQ 19 /* Request status of a dialplan entry */
|
||||
#define IAX_COMMAND_DPREP 20 /* Request status of a dialplan entry */
|
||||
#define IAX_COMMAND_DIAL 21 /* Request a dial on channel brought up TBD */
|
||||
#define IAX_COMMAND_TXREQ 22 /* Transfer Request */
|
||||
#define IAX_COMMAND_TXCNT 23 /* Transfer Connect */
|
||||
#define IAX_COMMAND_TXACC 24 /* Transfer Accepted */
|
||||
#define IAX_COMMAND_TXREADY 25 /* Transfer ready */
|
||||
#define IAX_COMMAND_TXREL 26 /* Transfer release */
|
||||
#define IAX_COMMAND_TXREJ 27 /* Transfer reject */
|
||||
#define IAX_COMMAND_QUELCH 28 /* Stop audio/video transmission */
|
||||
#define IAX_COMMAND_UNQUELCH 29 /* Resume audio/video transmission */
|
||||
|
||||
#define IAX_DEFAULT_REG_EXPIRE 60
|
||||
|
||||
#define IAX_DEFAULT_PORTNO 5036
|
||||
|
||||
/* Full frames are always delivered reliably */
|
||||
struct iax_full_hdr {
|
||||
short callno; /* Source call number -- high bit must be 1 */
|
||||
short dcallno; /* Destination call number */
|
||||
unsigned int ts; /* 32-bit timestamp in milliseconds */
|
||||
unsigned short seqno; /* Packet number */
|
||||
char type; /* Frame type */
|
||||
unsigned char csub; /* Compressed subclass */
|
||||
char data[0];
|
||||
};
|
||||
|
||||
/* Mini header is used only for voice frames -- delivered unreliably */
|
||||
struct iax_mini_hdr {
|
||||
short callno; /* Source call number -- high bit must be 0 */
|
||||
unsigned short ts; /* 16-bit Timestamp (high 16 bits from last IAX_full_hdr) */
|
||||
/* Frametype implicitly VOICE_FRAME */
|
||||
/* subclass implicit from last IAX_full_hdr */
|
||||
char data[0];
|
||||
};
|
||||
|
||||
#endif
|
822
utils/iaxclient/lib/libiax2/src/iax2-parser.c
Normal file
822
utils/iaxclient/lib/libiax2/src/iax2-parser.c
Normal file
|
@ -0,0 +1,822 @@
|
|||
/*
|
||||
* Asterisk -- A telephony toolkit for Linux.
|
||||
*
|
||||
* Implementation of Inter-Asterisk eXchange
|
||||
*
|
||||
* Copyright (C) 2003-2004, Digium
|
||||
*
|
||||
* Mark Spencer <markster@digium.com>
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU Lesser (Library) General Public License
|
||||
*/
|
||||
|
||||
#if defined(WIN32) || defined(_WIN32_WCE)
|
||||
#include "winpoop.h"
|
||||
#define snprintf _snprintf
|
||||
#else
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
#ifndef _MSC_VER
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "frame.h"
|
||||
#include "iax2.h"
|
||||
#include "iax2-parser.h"
|
||||
|
||||
static int frames = 0;
|
||||
static int iframes = 0;
|
||||
static int oframes = 0;
|
||||
|
||||
#ifdef ALIGN32
|
||||
static unsigned int get_uint32(unsigned char *p)
|
||||
{
|
||||
return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
|
||||
}
|
||||
|
||||
static unsigned short get_uint16(unsigned char *p)
|
||||
{
|
||||
return (p[0] << 8) | p[1] ;
|
||||
}
|
||||
|
||||
#else
|
||||
#define get_uint32(p) (*((unsigned int *)(p)))
|
||||
#define get_uint16(p) (*((unsigned short *)(p)))
|
||||
#endif
|
||||
|
||||
|
||||
static void internaloutput(const char *str)
|
||||
{
|
||||
//printf(str);
|
||||
}
|
||||
|
||||
static void internalerror(const char *str)
|
||||
{
|
||||
fprintf(stderr, "WARNING: %s", str);
|
||||
}
|
||||
|
||||
static void (*outputf)(const char *str) = internaloutput;
|
||||
static void (*errorf)(const char *str) = internalerror;
|
||||
|
||||
static void dump_addr(char *output, int maxlen, void *value, int len)
|
||||
{
|
||||
struct sockaddr_in sin;
|
||||
if (len == sizeof(sin)) {
|
||||
memcpy(&sin, value, len);
|
||||
snprintf(output, maxlen, "IPV4 %s:%d", inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
|
||||
} else {
|
||||
snprintf(output, maxlen, "Invalid Address");
|
||||
}
|
||||
}
|
||||
|
||||
static void dump_string(char *output, int maxlen, void *value, int len)
|
||||
{
|
||||
maxlen--;
|
||||
if (maxlen > len)
|
||||
maxlen = len;
|
||||
strncpy(output,(const char *)value, maxlen);
|
||||
output[maxlen] = '\0';
|
||||
}
|
||||
|
||||
static void dump_int(char *output, int maxlen, void *value, int len)
|
||||
{
|
||||
if (len == (int)sizeof(unsigned int))
|
||||
snprintf(output, maxlen, "%lu", (unsigned long)ntohl(get_uint32(value)));
|
||||
else
|
||||
snprintf(output, maxlen, "Invalid INT");
|
||||
}
|
||||
|
||||
static void dump_short(char *output, int maxlen, void *value, int len)
|
||||
{
|
||||
if (len == (int)sizeof(unsigned short))
|
||||
snprintf(output, maxlen, "%d", ntohs(get_uint16(value)));
|
||||
else
|
||||
snprintf(output, maxlen, "Invalid SHORT");
|
||||
}
|
||||
|
||||
static void dump_byte(char *output, int maxlen, void *value, int len)
|
||||
{
|
||||
if (len == (int)sizeof(unsigned char))
|
||||
snprintf(output, maxlen, "%d", *((unsigned char *)value));
|
||||
else
|
||||
snprintf(output, maxlen, "Invalid BYTE");
|
||||
}
|
||||
|
||||
static void dump_samprate(char *output, int maxlen, void *value, int len)
|
||||
{
|
||||
char tmp[256]="";
|
||||
int sr;
|
||||
if (len == (int)sizeof(unsigned short)) {
|
||||
sr = ntohs(*((unsigned short *)value));
|
||||
if (sr & IAX_RATE_8KHZ)
|
||||
strcat(tmp, ",8khz");
|
||||
if (sr & IAX_RATE_11KHZ)
|
||||
strcat(tmp, ",11.025khz");
|
||||
if (sr & IAX_RATE_16KHZ)
|
||||
strcat(tmp, ",16khz");
|
||||
if (sr & IAX_RATE_22KHZ)
|
||||
strcat(tmp, ",22.05khz");
|
||||
if (sr & IAX_RATE_44KHZ)
|
||||
strcat(tmp, ",44.1khz");
|
||||
if (sr & IAX_RATE_48KHZ)
|
||||
strcat(tmp, ",48khz");
|
||||
if (strlen(tmp))
|
||||
strncpy(output, &tmp[1], maxlen - 1);
|
||||
else
|
||||
strncpy(output, "None specified!\n", maxlen - 1);
|
||||
} else
|
||||
snprintf(output, maxlen, "Invalid SHORT");
|
||||
|
||||
}
|
||||
|
||||
static void dump_prov_ies(char *output, int maxlen, unsigned char *iedata, int len);
|
||||
static void dump_prov(char *output, int maxlen, void *value, int len)
|
||||
{
|
||||
dump_prov_ies(output, maxlen, (unsigned char *)value, len);
|
||||
}
|
||||
|
||||
static struct iax2_ie {
|
||||
int ie;
|
||||
char *name;
|
||||
void (*dump)(char *output, int maxlen, void *value, int len);
|
||||
} ies[] = {
|
||||
{ IAX_IE_CALLED_NUMBER, "CALLED NUMBER", dump_string },
|
||||
{ IAX_IE_CALLING_NUMBER, "CALLING NUMBER", dump_string },
|
||||
{ IAX_IE_CALLING_ANI, "ANI", dump_string },
|
||||
{ IAX_IE_CALLING_NAME, "CALLING NAME", dump_string },
|
||||
{ IAX_IE_CALLED_CONTEXT, "CALLED CONTEXT", dump_string },
|
||||
{ IAX_IE_USERNAME, "USERNAME", dump_string },
|
||||
{ IAX_IE_PASSWORD, "PASSWORD", dump_string },
|
||||
{ IAX_IE_CAPABILITY, "CAPABILITY", dump_int },
|
||||
{ IAX_IE_FORMAT, "FORMAT", dump_int },
|
||||
{ IAX_IE_LANGUAGE, "LANGUAGE", dump_string },
|
||||
{ IAX_IE_VERSION, "VERSION", dump_short },
|
||||
{ IAX_IE_ADSICPE, "ADSICPE", dump_short },
|
||||
{ IAX_IE_DNID, "DNID", dump_string },
|
||||
{ IAX_IE_AUTHMETHODS, "AUTHMETHODS", dump_short },
|
||||
{ IAX_IE_CHALLENGE, "CHALLENGE", dump_string },
|
||||
{ IAX_IE_MD5_RESULT, "MD5 RESULT", dump_string },
|
||||
{ IAX_IE_RSA_RESULT, "RSA RESULT", dump_string },
|
||||
{ IAX_IE_APPARENT_ADDR, "APPARENT ADDRESS", dump_addr },
|
||||
{ IAX_IE_REFRESH, "REFRESH", dump_short },
|
||||
{ IAX_IE_DPSTATUS, "DIALPLAN STATUS", dump_short },
|
||||
{ IAX_IE_CALLNO, "CALL NUMBER", dump_short },
|
||||
{ IAX_IE_CAUSE, "CAUSE", dump_string },
|
||||
{ IAX_IE_IAX_UNKNOWN, "UNKNOWN IAX CMD", dump_byte },
|
||||
{ IAX_IE_MSGCOUNT, "MESSAGE COUNT", dump_short },
|
||||
{ IAX_IE_AUTOANSWER, "AUTO ANSWER REQ" },
|
||||
{ IAX_IE_TRANSFERID, "TRANSFER ID", dump_int },
|
||||
{ IAX_IE_RDNIS, "REFERRING DNIS", dump_string },
|
||||
{ IAX_IE_PROVISIONING, "PROVISIONING", dump_prov },
|
||||
{ IAX_IE_AESPROVISIONING, "AES PROVISIONG" },
|
||||
{ IAX_IE_DATETIME, "DATE TIME", dump_int },
|
||||
{ IAX_IE_DEVICETYPE, "DEVICE TYPE", dump_string },
|
||||
{ IAX_IE_SERVICEIDENT, "SERVICE IDENT", dump_string },
|
||||
{ IAX_IE_FIRMWAREVER, "FIRMWARE VER", dump_short },
|
||||
{ IAX_IE_FWBLOCKDESC, "FW BLOCK DESC", dump_int },
|
||||
{ IAX_IE_FWBLOCKDATA, "FW BLOCK DATA" },
|
||||
{ IAX_IE_PROVVER, "PROVISIONG VER", dump_int },
|
||||
{ IAX_IE_CALLINGPRES, "CALLING PRESNTN", dump_byte },
|
||||
{ IAX_IE_CALLINGTON, "CALLING TYPEOFNUM", dump_byte },
|
||||
{ IAX_IE_CALLINGTNS, "CALLING TRANSITNET", dump_short },
|
||||
{ IAX_IE_SAMPLINGRATE, "SAMPLINGRATE", dump_samprate },
|
||||
{ IAX_IE_CODEC_PREFS, "CODEC_PREFS", dump_string },
|
||||
{ IAX_IE_RR_JITTER, "RR_JITTER", dump_int },
|
||||
{ IAX_IE_RR_LOSS, "RR_LOSS", dump_int },
|
||||
{ IAX_IE_RR_PKTS, "RR_PKTS", dump_int },
|
||||
{ IAX_IE_RR_DELAY, "RR_DELAY", dump_short },
|
||||
{ IAX_IE_RR_DROPPED, "RR_DROPPED", dump_int },
|
||||
{ IAX_IE_RR_OOO, "RR_OOO", dump_int },
|
||||
};
|
||||
|
||||
const char *iax_ie2str(int ie)
|
||||
{
|
||||
int x;
|
||||
for (x=0;x<(int)sizeof(ies) / (int)sizeof(ies[0]); x++) {
|
||||
if (ies[x].ie == ie)
|
||||
return ies[x].name;
|
||||
}
|
||||
return "Unknown IE";
|
||||
}
|
||||
|
||||
|
||||
static void dump_prov_ies(char *output, int maxlen, unsigned char *iedata, int len)
|
||||
{
|
||||
int ielen;
|
||||
int ie;
|
||||
int found;
|
||||
char tmp[256];
|
||||
if (len < 2)
|
||||
return;
|
||||
strcpy(output, "\n");
|
||||
maxlen -= (int)strlen(output); output += strlen(output);
|
||||
while(len > 2) {
|
||||
ie = iedata[0];
|
||||
ielen = iedata[1];
|
||||
if (ielen + 2> len) {
|
||||
snprintf(tmp, (int)sizeof(tmp), "Total Prov IE length of %d bytes exceeds remaining prov frame length of %d bytes\n", ielen + 2, len);
|
||||
strncpy(output, tmp, maxlen - 1);
|
||||
maxlen -= (int)strlen(output); output += strlen(output);
|
||||
return;
|
||||
}
|
||||
found = 0;
|
||||
if (!found) {
|
||||
snprintf(tmp, (int)sizeof(tmp), " Unknown Prov IE %03d : Present\n", ie);
|
||||
strncpy(output, tmp, maxlen - 1);
|
||||
maxlen -= (int)strlen(output); output += strlen(output);
|
||||
}
|
||||
iedata += (2 + ielen);
|
||||
len -= (2 + ielen);
|
||||
}
|
||||
}
|
||||
|
||||
static void dump_ies(unsigned char *iedata, int len)
|
||||
{
|
||||
int ielen;
|
||||
int ie;
|
||||
int x;
|
||||
int found;
|
||||
char interp[1024];
|
||||
char tmp[1024];
|
||||
if (len < 2)
|
||||
return;
|
||||
while(len > 2) {
|
||||
ie = iedata[0];
|
||||
ielen = iedata[1];
|
||||
if (ielen + 2> len) {
|
||||
snprintf(tmp, (int)sizeof(tmp), "Total IE length of %d bytes exceeds remaining frame length of %d bytes\n", ielen + 2, len);
|
||||
outputf(tmp);
|
||||
return;
|
||||
}
|
||||
found = 0;
|
||||
for (x=0;x<(int)sizeof(ies) / (int)sizeof(ies[0]); x++) {
|
||||
if (ies[x].ie == ie) {
|
||||
if (ies[x].dump) {
|
||||
ies[x].dump(interp, (int)sizeof(interp), iedata + 2, ielen);
|
||||
snprintf(tmp, (int)sizeof(tmp), " %-15.15s : %s\n", ies[x].name, interp);
|
||||
outputf(tmp);
|
||||
} else {
|
||||
if (ielen)
|
||||
snprintf(interp, (int)sizeof(interp), "%d bytes", ielen);
|
||||
else
|
||||
strcpy(interp, "Present");
|
||||
snprintf(tmp, (int)sizeof(tmp), " %-15.15s : %s\n", ies[x].name, interp);
|
||||
outputf(tmp);
|
||||
}
|
||||
found++;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
snprintf(tmp, (int)sizeof(tmp), " Unknown IE %03d : Present\n", ie);
|
||||
outputf(tmp);
|
||||
}
|
||||
iedata += (2 + ielen);
|
||||
len -= (2 + ielen);
|
||||
}
|
||||
outputf("\n");
|
||||
}
|
||||
|
||||
void iax_showframe(struct iax_frame *f, struct ast_iax2_full_hdr *fhi, int rx, struct sockaddr_in *sin, int datalen)
|
||||
{
|
||||
const char *frames[] = {
|
||||
"(0?)",
|
||||
"DTMF ",
|
||||
"VOICE ",
|
||||
"VIDEO ",
|
||||
"CONTROL",
|
||||
"NULL ",
|
||||
"IAX ",
|
||||
"TEXT ",
|
||||
"IMAGE " };
|
||||
const char *iaxs[] = {
|
||||
"(0?)",
|
||||
"NEW ",
|
||||
"PING ",
|
||||
"PONG ",
|
||||
"ACK ",
|
||||
"HANGUP ",
|
||||
"REJECT ",
|
||||
"ACCEPT ",
|
||||
"AUTHREQ",
|
||||
"AUTHREP",
|
||||
"INVAL ",
|
||||
"LAGRQ ",
|
||||
"LAGRP ",
|
||||
"REGREQ ",
|
||||
"REGAUTH",
|
||||
"REGACK ",
|
||||
"REGREJ ",
|
||||
"REGREL ",
|
||||
"VNAK ",
|
||||
"DPREQ ",
|
||||
"DPREP ",
|
||||
"DIAL ",
|
||||
"TXREQ ",
|
||||
"TXCNT ",
|
||||
"TXACC ",
|
||||
"TXREADY",
|
||||
"TXREL ",
|
||||
"TXREJ ",
|
||||
"QUELCH ",
|
||||
"UNQULCH",
|
||||
"POKE",
|
||||
"PAGE",
|
||||
"MWI",
|
||||
"UNSUPPORTED",
|
||||
"TRANSFER",
|
||||
"PROVISION",
|
||||
"FWDOWNLD",
|
||||
"FWDATA"
|
||||
};
|
||||
const char *cmds[] = {
|
||||
"(0?)",
|
||||
"HANGUP ",
|
||||
"RING ",
|
||||
"RINGING",
|
||||
"ANSWER ",
|
||||
"BUSY ",
|
||||
"TKOFFHK ",
|
||||
"OFFHOOK ",
|
||||
"CONGESTION ",
|
||||
"FLASH ",
|
||||
"WINK ",
|
||||
"OPTION "
|
||||
};
|
||||
struct ast_iax2_full_hdr *fh;
|
||||
char retries[20];
|
||||
char class2[20];
|
||||
char subclass2[20];
|
||||
const char *clas;
|
||||
const char *subclass;
|
||||
char tmp[256];
|
||||
|
||||
if (f) {
|
||||
fh = (struct ast_iax2_full_hdr *)f->data;
|
||||
snprintf(retries, (int)sizeof(retries), "%03d", f->retries);
|
||||
} else {
|
||||
fh = fhi;
|
||||
if (ntohs(fh->dcallno) & IAX_FLAG_RETRANS)
|
||||
strcpy(retries, "Yes");
|
||||
else
|
||||
strcpy(retries, " No");
|
||||
}
|
||||
if (!(ntohs(fh->scallno) & IAX_FLAG_FULL)) {
|
||||
/* Don't mess with mini-frames */
|
||||
return;
|
||||
}
|
||||
if (fh->type >= (int)(sizeof(frames)/sizeof(char *))) {
|
||||
snprintf(class2, (int)sizeof(class2), "(%d?)", fh->type);
|
||||
clas = class2;
|
||||
} else {
|
||||
clas = frames[(int)fh->type];
|
||||
}
|
||||
if (fh->type == AST_FRAME_DTMF) {
|
||||
sprintf(subclass2, "%c", fh->csub);
|
||||
subclass = subclass2;
|
||||
} else if (fh->type == AST_FRAME_IAX) {
|
||||
if (fh->csub >= (int)sizeof(iaxs)/(int)sizeof(iaxs[0])) {
|
||||
snprintf(subclass2, (int)sizeof(subclass2), "(%d?)", fh->csub);
|
||||
subclass = subclass2;
|
||||
} else {
|
||||
subclass = iaxs[(int)fh->csub];
|
||||
}
|
||||
} else if (fh->type == AST_FRAME_CONTROL) {
|
||||
if (fh->csub >= (int)(sizeof(cmds)/sizeof(char *))) {
|
||||
snprintf(subclass2, (int)sizeof(subclass2), "(%d?)", fh->csub);
|
||||
subclass = subclass2;
|
||||
} else {
|
||||
subclass = cmds[(int)fh->csub];
|
||||
}
|
||||
} else {
|
||||
snprintf(subclass2, (int)sizeof(subclass2), "%d", fh->csub);
|
||||
subclass = subclass2;
|
||||
}
|
||||
snprintf(tmp, (int)sizeof(tmp),
|
||||
"%s-Frame Retry[%s] -- OSeqno: %3.3d ISeqno: %3.3d Type: %s Subclass: %s\n",
|
||||
(rx ? "Rx" : "Tx"),
|
||||
retries, fh->oseqno, fh->iseqno, clas, subclass);
|
||||
outputf(tmp);
|
||||
snprintf(tmp, (int)sizeof(tmp),
|
||||
" Timestamp: %05lums SCall: %5.5d DCall: %5.5d [%s:%d]\n",
|
||||
(unsigned long)ntohl(fh->ts),
|
||||
ntohs(fh->scallno) & ~IAX_FLAG_FULL, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS,
|
||||
inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
|
||||
outputf(tmp);
|
||||
if (fh->type == AST_FRAME_IAX)
|
||||
dump_ies(fh->iedata, datalen);
|
||||
}
|
||||
|
||||
int iax_ie_append_raw(struct iax_ie_data *ied, unsigned char ie, const void *data, int datalen)
|
||||
{
|
||||
char tmp[256];
|
||||
if (datalen > ((int)sizeof(ied->buf) - ied->pos)) {
|
||||
snprintf(tmp, (int)sizeof(tmp), "Out of space for ie '%s' (%d), need %d have %d\n", iax_ie2str(ie), ie, datalen, (int)sizeof(ied->buf) - ied->pos);
|
||||
errorf(tmp);
|
||||
return -1;
|
||||
}
|
||||
ied->buf[ied->pos++] = ie;
|
||||
ied->buf[ied->pos++] = datalen;
|
||||
memcpy(ied->buf + ied->pos, data, datalen);
|
||||
ied->pos += datalen;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int iax_ie_append_addr(struct iax_ie_data *ied, unsigned char ie, struct sockaddr_in *sin)
|
||||
{
|
||||
return iax_ie_append_raw(ied, ie, sin, (int)sizeof(struct sockaddr_in));
|
||||
}
|
||||
|
||||
int iax_ie_append_int(struct iax_ie_data *ied, unsigned char ie, unsigned int value)
|
||||
{
|
||||
unsigned int newval;
|
||||
newval = htonl(value);
|
||||
return iax_ie_append_raw(ied, ie, &newval, (int)sizeof(newval));
|
||||
}
|
||||
|
||||
int iax_ie_append_short(struct iax_ie_data *ied, unsigned char ie, unsigned short value)
|
||||
{
|
||||
unsigned short newval;
|
||||
newval = htons(value);
|
||||
return iax_ie_append_raw(ied, ie, &newval, (int)sizeof(newval));
|
||||
}
|
||||
|
||||
int iax_ie_append_str(struct iax_ie_data *ied, unsigned char ie, const char *str)
|
||||
{
|
||||
return iax_ie_append_raw(ied, ie, str, (int)strlen(str));
|
||||
}
|
||||
|
||||
int iax_ie_append_byte(struct iax_ie_data *ied, unsigned char ie, unsigned char dat)
|
||||
{
|
||||
return iax_ie_append_raw(ied, ie, &dat, 1);
|
||||
}
|
||||
|
||||
int iax_ie_append(struct iax_ie_data *ied, unsigned char ie)
|
||||
{
|
||||
return iax_ie_append_raw(ied, ie, NULL, 0);
|
||||
}
|
||||
|
||||
void iax_set_output(void (*func)(const char *))
|
||||
{
|
||||
outputf = func;
|
||||
}
|
||||
|
||||
void iax_set_error(void (*func)(const char *))
|
||||
{
|
||||
errorf = func;
|
||||
}
|
||||
|
||||
int iax_parse_ies(struct iax_ies *ies, unsigned char *data, int datalen)
|
||||
{
|
||||
/* Parse data into information elements */
|
||||
int len;
|
||||
int ie;
|
||||
char tmp[256];
|
||||
memset(ies, 0, (int)sizeof(struct iax_ies));
|
||||
ies->msgcount = -1;
|
||||
ies->firmwarever = -1;
|
||||
ies->calling_ton = -1;
|
||||
ies->calling_tns = -1;
|
||||
ies->calling_pres = -1;
|
||||
ies->samprate = IAX_RATE_8KHZ;
|
||||
while(datalen >= 2) {
|
||||
ie = data[0];
|
||||
len = data[1];
|
||||
if (len > datalen - 2) {
|
||||
errorf("Information element length exceeds message size\n");
|
||||
return -1;
|
||||
}
|
||||
switch(ie) {
|
||||
case IAX_IE_CALLED_NUMBER:
|
||||
ies->called_number = (char *) data + 2;
|
||||
break;
|
||||
case IAX_IE_CALLING_NUMBER:
|
||||
ies->calling_number = (char *) data + 2;
|
||||
break;
|
||||
case IAX_IE_CALLING_ANI:
|
||||
ies->calling_ani = (char *) data + 2;
|
||||
break;
|
||||
case IAX_IE_CALLING_NAME:
|
||||
ies->calling_name = (char *) data + 2;
|
||||
break;
|
||||
case IAX_IE_CALLED_CONTEXT:
|
||||
ies->called_context = (char *) data + 2;
|
||||
break;
|
||||
case IAX_IE_USERNAME:
|
||||
ies->username = (char *) data + 2;
|
||||
break;
|
||||
case IAX_IE_PASSWORD:
|
||||
ies->password = (char *) data + 2;
|
||||
break;
|
||||
case IAX_IE_CAPABILITY:
|
||||
if (len != (int)sizeof(unsigned int)) {
|
||||
snprintf(tmp, (int)sizeof(tmp), "Expecting capability to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
|
||||
errorf(tmp);
|
||||
} else
|
||||
ies->capability = ntohl(get_uint32(data + 2));
|
||||
break;
|
||||
case IAX_IE_FORMAT:
|
||||
if (len != (int)sizeof(unsigned int)) {
|
||||
snprintf(tmp, (int)sizeof(tmp), "Expecting format to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
|
||||
errorf(tmp);
|
||||
} else
|
||||
ies->format = ntohl(get_uint32(data + 2));
|
||||
break;
|
||||
case IAX_IE_LANGUAGE:
|
||||
ies->language = (char *) data + 2;
|
||||
break;
|
||||
case IAX_IE_CODEC_PREFS:
|
||||
ies->codec_prefs = (char *) data + 2;
|
||||
break;
|
||||
case IAX_IE_VERSION:
|
||||
if (len != (int)sizeof(unsigned short)) {
|
||||
snprintf(tmp, (int)sizeof(tmp), "Expecting version to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
|
||||
errorf(tmp);
|
||||
} else
|
||||
ies->version = ntohs(get_uint16(data + 2));
|
||||
break;
|
||||
case IAX_IE_ADSICPE:
|
||||
if (len != (int)sizeof(unsigned short)) {
|
||||
snprintf(tmp, (int)sizeof(tmp), "Expecting adsicpe to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
|
||||
errorf(tmp);
|
||||
} else
|
||||
ies->adsicpe = ntohs(get_uint16(data + 2));
|
||||
break;
|
||||
case IAX_IE_SAMPLINGRATE:
|
||||
if (len != (int)sizeof(unsigned short)) {
|
||||
snprintf(tmp, (int)sizeof(tmp), "Expecting samplingrate to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
|
||||
errorf(tmp);
|
||||
} else
|
||||
ies->samprate = ntohs(get_uint16(data + 2));
|
||||
break;
|
||||
case IAX_IE_DNID:
|
||||
ies->dnid = (char *) data + 2;
|
||||
break;
|
||||
case IAX_IE_RDNIS:
|
||||
ies->rdnis = (char *) data + 2;
|
||||
break;
|
||||
case IAX_IE_AUTHMETHODS:
|
||||
if (len != (int)sizeof(unsigned short)) {
|
||||
snprintf(tmp, (int)sizeof(tmp), "Expecting authmethods to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
|
||||
errorf(tmp);
|
||||
} else
|
||||
ies->authmethods = ntohs(get_uint16(data + 2));
|
||||
break;
|
||||
case IAX_IE_CHALLENGE:
|
||||
ies->challenge = (char *) data + 2;
|
||||
break;
|
||||
case IAX_IE_MD5_RESULT:
|
||||
ies->md5_result = (char *) data + 2;
|
||||
break;
|
||||
case IAX_IE_RSA_RESULT:
|
||||
ies->rsa_result = (char *) data + 2;
|
||||
break;
|
||||
case IAX_IE_APPARENT_ADDR:
|
||||
ies->apparent_addr = ((struct sockaddr_in *)(data + 2));
|
||||
break;
|
||||
case IAX_IE_REFRESH:
|
||||
if (len != (int)sizeof(unsigned short)) {
|
||||
snprintf(tmp, (int)sizeof(tmp), "Expecting refresh to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
|
||||
errorf(tmp);
|
||||
} else
|
||||
ies->refresh = ntohs(get_uint16(data + 2));
|
||||
break;
|
||||
case IAX_IE_DPSTATUS:
|
||||
if (len != (int)sizeof(unsigned short)) {
|
||||
snprintf(tmp, (int)sizeof(tmp), "Expecting dpstatus to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
|
||||
errorf(tmp);
|
||||
} else
|
||||
ies->dpstatus = ntohs(get_uint16(data + 2));
|
||||
break;
|
||||
case IAX_IE_CALLNO:
|
||||
if (len != (int)sizeof(unsigned short)) {
|
||||
snprintf(tmp, (int)sizeof(tmp), "Expecting callno to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
|
||||
errorf(tmp);
|
||||
} else
|
||||
ies->callno = ntohs(get_uint16(data + 2));
|
||||
break;
|
||||
case IAX_IE_CAUSE:
|
||||
ies->cause = (char *) data + 2;
|
||||
break;
|
||||
case IAX_IE_CAUSECODE:
|
||||
if (len != 1) {
|
||||
snprintf(tmp, (int)sizeof(tmp), "Expecting causecode to be single byte but was %d\n", len);
|
||||
errorf(tmp);
|
||||
} else {
|
||||
ies->causecode = data[2];
|
||||
}
|
||||
break;
|
||||
case IAX_IE_IAX_UNKNOWN:
|
||||
if (len == 1)
|
||||
ies->iax_unknown = data[2];
|
||||
else {
|
||||
snprintf(tmp, (int)sizeof(tmp), "Expected single byte Unknown command, but was %d long\n", len);
|
||||
errorf(tmp);
|
||||
}
|
||||
break;
|
||||
case IAX_IE_MSGCOUNT:
|
||||
if (len != (int)sizeof(unsigned short)) {
|
||||
snprintf(tmp, (int)sizeof(tmp), "Expecting msgcount to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
|
||||
errorf(tmp);
|
||||
} else
|
||||
ies->msgcount = ntohs(get_uint16(data + 2));
|
||||
break;
|
||||
case IAX_IE_AUTOANSWER:
|
||||
ies->autoanswer = 1;
|
||||
break;
|
||||
case IAX_IE_MUSICONHOLD:
|
||||
ies->musiconhold = 1;
|
||||
break;
|
||||
case IAX_IE_TRANSFERID:
|
||||
if (len != (int)sizeof(unsigned int)) {
|
||||
snprintf(tmp, (int)sizeof(tmp), "Expecting transferid to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
|
||||
errorf(tmp);
|
||||
} else
|
||||
ies->transferid = ntohl(get_uint32(data + 2));
|
||||
break;
|
||||
case IAX_IE_DATETIME:
|
||||
if (len != (int)sizeof(unsigned int)) {
|
||||
snprintf(tmp, (int)sizeof(tmp), "Expecting date/time to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
|
||||
errorf(tmp);
|
||||
} else
|
||||
ies->datetime = ntohl(get_uint32(data + 2));
|
||||
break;
|
||||
case IAX_IE_FIRMWAREVER:
|
||||
if (len != (int)sizeof(unsigned short)) {
|
||||
snprintf(tmp, (int)sizeof(tmp), "Expecting firmwarever to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
|
||||
errorf(tmp);
|
||||
} else
|
||||
ies->firmwarever = ntohs(get_uint16(data + 2));
|
||||
break;
|
||||
case IAX_IE_DEVICETYPE:
|
||||
ies->devicetype = (char *) data + 2;
|
||||
break;
|
||||
case IAX_IE_SERVICEIDENT:
|
||||
ies->serviceident = (char *) data + 2;
|
||||
break;
|
||||
case IAX_IE_FWBLOCKDESC:
|
||||
if (len != (int)sizeof(unsigned int)) {
|
||||
snprintf(tmp, (int)sizeof(tmp), "Expected block desc to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
|
||||
errorf(tmp);
|
||||
} else
|
||||
ies->fwdesc = ntohl(get_uint32(data + 2));
|
||||
break;
|
||||
case IAX_IE_FWBLOCKDATA:
|
||||
ies->fwdata = data + 2;
|
||||
ies->fwdatalen = len;
|
||||
break;
|
||||
case IAX_IE_PROVVER:
|
||||
if (len != (int)sizeof(unsigned int)) {
|
||||
snprintf(tmp, (int)sizeof(tmp), "Expected provisioning version to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
|
||||
errorf(tmp);
|
||||
} else {
|
||||
ies->provverpres = 1;
|
||||
ies->provver = ntohl(get_uint32(data + 2));
|
||||
}
|
||||
break;
|
||||
case IAX_IE_CALLINGPRES:
|
||||
if (len == 1)
|
||||
ies->calling_pres = data[2];
|
||||
else {
|
||||
snprintf(tmp, (int)sizeof(tmp), "Expected single byte callingpres, but was %d long\n", len);
|
||||
errorf(tmp);
|
||||
}
|
||||
break;
|
||||
case IAX_IE_CALLINGTON:
|
||||
if (len == 1)
|
||||
ies->calling_ton = data[2];
|
||||
else {
|
||||
snprintf(tmp, (int)sizeof(tmp), "Expected single byte callington, but was %d long\n", len);
|
||||
errorf(tmp);
|
||||
}
|
||||
break;
|
||||
case IAX_IE_CALLINGTNS:
|
||||
if (len != (int)sizeof(unsigned short)) {
|
||||
snprintf(tmp, (int)sizeof(tmp), "Expecting callingtns to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
|
||||
errorf(tmp);
|
||||
} else
|
||||
ies->calling_tns = ntohs(get_uint16(data + 2));
|
||||
break;
|
||||
case IAX_IE_RR_JITTER:
|
||||
if (len != (int)sizeof(unsigned int)) {
|
||||
snprintf(tmp, (int)sizeof(tmp), "Expected jitter rr to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
|
||||
errorf(tmp);
|
||||
} else {
|
||||
ies->rr_jitter = ntohl(get_uint32(data + 2));
|
||||
}
|
||||
break;
|
||||
case IAX_IE_RR_LOSS:
|
||||
if (len != (int)sizeof(unsigned int)) {
|
||||
snprintf(tmp, (int)sizeof(tmp), "Expected loss rr to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
|
||||
errorf(tmp);
|
||||
} else {
|
||||
ies->rr_loss = ntohl(get_uint32(data + 2));
|
||||
}
|
||||
break;
|
||||
case IAX_IE_RR_PKTS:
|
||||
if (len != (int)sizeof(unsigned int)) {
|
||||
snprintf(tmp, (int)sizeof(tmp), "Expected packets rr to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
|
||||
errorf(tmp);
|
||||
} else {
|
||||
ies->rr_pkts = ntohl(get_uint32(data + 2));
|
||||
}
|
||||
break;
|
||||
case IAX_IE_RR_DELAY:
|
||||
if (len != (int)sizeof(unsigned short)) {
|
||||
snprintf(tmp, (int)sizeof(tmp), "Expected loss rr to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
|
||||
errorf(tmp);
|
||||
} else {
|
||||
ies->rr_delay = ntohs(get_uint16(data + 2));
|
||||
}
|
||||
break;
|
||||
case IAX_IE_RR_DROPPED:
|
||||
if (len != (int)sizeof(unsigned int)) {
|
||||
snprintf(tmp, (int)sizeof(tmp), "Expected packets rr to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
|
||||
errorf(tmp);
|
||||
} else {
|
||||
ies->rr_dropped = ntohl(get_uint32(data + 2));
|
||||
}
|
||||
break;
|
||||
case IAX_IE_RR_OOO:
|
||||
if (len != (int)sizeof(unsigned int)) {
|
||||
snprintf(tmp, (int)sizeof(tmp), "Expected packets rr to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
|
||||
errorf(tmp);
|
||||
} else {
|
||||
ies->rr_ooo = ntohl(get_uint32(data + 2));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
snprintf(tmp, (int)sizeof(tmp), "Ignoring unknown information element '%s' (%d) of length %d\n", iax_ie2str(ie), ie, len);
|
||||
outputf(tmp);
|
||||
}
|
||||
/* Overwrite information element with 0, to null terminate previous portion */
|
||||
data[0] = 0;
|
||||
datalen -= (len + 2);
|
||||
data += (len + 2);
|
||||
}
|
||||
/* Null-terminate last field */
|
||||
*data = '\0';
|
||||
if (datalen) {
|
||||
errorf("Invalid information element contents, strange boundary\n");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void iax_frame_wrap(struct iax_frame *fr, struct ast_frame *f)
|
||||
{
|
||||
fr->af.frametype = f->frametype;
|
||||
fr->af.subclass = f->subclass;
|
||||
fr->af.mallocd = 0; /* Our frame is static relative to the container */
|
||||
fr->af.datalen = f->datalen;
|
||||
fr->af.samples = f->samples;
|
||||
fr->af.offset = AST_FRIENDLY_OFFSET;
|
||||
fr->af.src = f->src;
|
||||
fr->af.data = fr->afdata;
|
||||
if (fr->af.datalen)
|
||||
memcpy(fr->af.data, f->data, fr->af.datalen);
|
||||
}
|
||||
|
||||
struct iax_frame *iax_frame_new(int direction, int datalen)
|
||||
{
|
||||
struct iax_frame *fr;
|
||||
fr = (struct iax_frame *)malloc((int)sizeof(struct iax_frame) + datalen);
|
||||
if (fr) {
|
||||
fr->direction = direction;
|
||||
fr->retrans = -1;
|
||||
frames++;
|
||||
if (fr->direction == DIRECTION_INGRESS)
|
||||
iframes++;
|
||||
else
|
||||
oframes++;
|
||||
}
|
||||
return fr;
|
||||
}
|
||||
|
||||
void iax_frame_free(struct iax_frame *fr)
|
||||
{
|
||||
/* Note: does not remove from scheduler! */
|
||||
if (fr->direction == DIRECTION_INGRESS)
|
||||
iframes--;
|
||||
else if (fr->direction == DIRECTION_OUTGRESS)
|
||||
oframes--;
|
||||
else {
|
||||
errorf("Attempt to double free frame detected\n");
|
||||
return;
|
||||
}
|
||||
fr->direction = 0;
|
||||
free(fr);
|
||||
frames--;
|
||||
}
|
||||
|
||||
int iax_get_frames(void) { return frames; }
|
||||
int iax_get_iframes(void) { return iframes; }
|
||||
int iax_get_oframes(void) { return oframes; }
|
146
utils/iaxclient/lib/libiax2/src/iax2-parser.h
Normal file
146
utils/iaxclient/lib/libiax2/src/iax2-parser.h
Normal file
|
@ -0,0 +1,146 @@
|
|||
/*
|
||||
* Asterisk -- A telephony toolkit for Linux.
|
||||
*
|
||||
* Implementation of Inter-Asterisk eXchange
|
||||
*
|
||||
* Copyright (C) 2003, Digium
|
||||
*
|
||||
* Mark Spencer <markster@digium.com>
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU Lesser (Library) General Public License
|
||||
*/
|
||||
|
||||
#ifndef _IAX2_PARSER_H
|
||||
#define _IAX2_PARSER_H
|
||||
|
||||
struct iax_ies {
|
||||
char *called_number;
|
||||
char *calling_number;
|
||||
char *calling_ani;
|
||||
char *calling_name;
|
||||
int calling_ton;
|
||||
int calling_tns;
|
||||
int calling_pres;
|
||||
char *called_context;
|
||||
char *username;
|
||||
char *password;
|
||||
unsigned int capability;
|
||||
unsigned int format;
|
||||
char *codec_prefs;
|
||||
char *language;
|
||||
int version;
|
||||
unsigned short adsicpe;
|
||||
char *dnid;
|
||||
char *rdnis;
|
||||
unsigned int authmethods;
|
||||
char *challenge;
|
||||
char *md5_result;
|
||||
char *rsa_result;
|
||||
struct sockaddr_in *apparent_addr;
|
||||
unsigned short refresh;
|
||||
unsigned short dpstatus;
|
||||
unsigned short callno;
|
||||
char *cause;
|
||||
unsigned char causecode;
|
||||
unsigned char iax_unknown;
|
||||
int msgcount;
|
||||
int autoanswer;
|
||||
int musiconhold;
|
||||
unsigned int transferid;
|
||||
unsigned int datetime;
|
||||
char *devicetype;
|
||||
char *serviceident;
|
||||
int firmwarever;
|
||||
unsigned int fwdesc;
|
||||
unsigned char *fwdata;
|
||||
unsigned char fwdatalen;
|
||||
unsigned int provver;
|
||||
unsigned short samprate;
|
||||
unsigned int provverpres;
|
||||
unsigned int rr_jitter;
|
||||
unsigned int rr_loss;
|
||||
unsigned int rr_pkts;
|
||||
unsigned short rr_delay;
|
||||
unsigned int rr_dropped;
|
||||
unsigned int rr_ooo;
|
||||
};
|
||||
|
||||
#define DIRECTION_INGRESS 1
|
||||
#define DIRECTION_OUTGRESS 2
|
||||
|
||||
struct iax_frame {
|
||||
#ifdef LIBIAX
|
||||
struct iax_session *session;
|
||||
struct iax_event *event;
|
||||
#endif
|
||||
|
||||
/* /Our/ call number */
|
||||
unsigned short callno;
|
||||
/* /Their/ call number */
|
||||
unsigned short dcallno;
|
||||
/* Start of raw frame (outgoing only) */
|
||||
void *data;
|
||||
/* Length of frame (outgoing only) */
|
||||
int datalen;
|
||||
/* How many retries so far? */
|
||||
int retries;
|
||||
/* Outgoing relative timestamp (ms) */
|
||||
unsigned int ts;
|
||||
/* How long to wait before retrying */
|
||||
int retrytime;
|
||||
/* Are we received out of order? */
|
||||
int outoforder;
|
||||
/* Have we been sent at all yet? */
|
||||
int sentyet;
|
||||
/* Outgoing Packet sequence number */
|
||||
int oseqno;
|
||||
/* Next expected incoming packet sequence number */
|
||||
int iseqno;
|
||||
/* Non-zero if should be sent to transfer peer */
|
||||
int transfer;
|
||||
/* Non-zero if this is the final message */
|
||||
int final;
|
||||
/* Ingress or outgres */
|
||||
int direction;
|
||||
/* Retransmission ID */
|
||||
int retrans;
|
||||
/* Easy linking */
|
||||
struct iax_frame *next;
|
||||
struct iax_frame *prev;
|
||||
/* Actual, isolated frame header */
|
||||
struct ast_frame af;
|
||||
unsigned char unused[AST_FRIENDLY_OFFSET];
|
||||
unsigned char afdata[0]; /* Data for frame */
|
||||
};
|
||||
|
||||
struct iax_ie_data {
|
||||
unsigned char buf[1024];
|
||||
int pos;
|
||||
};
|
||||
|
||||
/* Choose a different function for output */
|
||||
extern void iax_set_output(void (*output)(const char *data));
|
||||
/* Choose a different function for errors */
|
||||
extern void iax_set_error(void (*output)(const char *data));
|
||||
extern void iax_showframe(struct iax_frame *f, struct ast_iax2_full_hdr *fhi, int rx, struct sockaddr_in *sin, int datalen);
|
||||
|
||||
extern const char *iax_ie2str(int ie);
|
||||
|
||||
extern int iax_ie_append_raw(struct iax_ie_data *ied, unsigned char ie, const void *data, int datalen);
|
||||
extern int iax_ie_append_addr(struct iax_ie_data *ied, unsigned char ie, struct sockaddr_in *sin);
|
||||
extern int iax_ie_append_int(struct iax_ie_data *ied, unsigned char ie, unsigned int value);
|
||||
extern int iax_ie_append_short(struct iax_ie_data *ied, unsigned char ie, unsigned short value);
|
||||
extern int iax_ie_append_str(struct iax_ie_data *ied, unsigned char ie, const char *str);
|
||||
extern int iax_ie_append_byte(struct iax_ie_data *ied, unsigned char ie, unsigned char dat);
|
||||
extern int iax_ie_append(struct iax_ie_data *ied, unsigned char ie);
|
||||
extern int iax_parse_ies(struct iax_ies *ies, unsigned char *data, int datalen);
|
||||
|
||||
extern int iax_get_frames(void);
|
||||
extern int iax_get_iframes(void);
|
||||
extern int iax_get_oframes(void);
|
||||
|
||||
extern void iax_frame_wrap(struct iax_frame *fr, struct ast_frame *f);
|
||||
extern struct iax_frame *iax_frame_new(int direction, int datalen);
|
||||
extern void iax_frame_free(struct iax_frame *fr);
|
||||
#endif
|
223
utils/iaxclient/lib/libiax2/src/iax2.h
Normal file
223
utils/iaxclient/lib/libiax2/src/iax2.h
Normal file
|
@ -0,0 +1,223 @@
|
|||
/*
|
||||
* Asterisk -- A telephony toolkit for Linux.
|
||||
*
|
||||
* Implementation of Inter-Asterisk eXchange
|
||||
*
|
||||
* Copyright (C) 2003, Digium
|
||||
*
|
||||
* Mark Spencer <markster@linux-support.net>
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU Lesser (Library) General Public License
|
||||
*/
|
||||
|
||||
#ifndef _IAX2_H
|
||||
#define _IAX2_H
|
||||
|
||||
/* Max version of IAX protocol we support */
|
||||
#define IAX_PROTO_VERSION 2
|
||||
|
||||
#define IAX_MAX_CALLS 32768
|
||||
|
||||
#define IAX_FLAG_FULL 0x8000
|
||||
|
||||
#define IAX_FLAG_RETRANS 0x8000
|
||||
|
||||
#define IAX_FLAG_SC_LOG 0x80
|
||||
|
||||
#define IAX_MAX_SHIFT 0x1F
|
||||
|
||||
#define IAX_WINDOW 64
|
||||
|
||||
/* Subclass for AST_FRAME_IAX */
|
||||
#define IAX_COMMAND_NEW 1
|
||||
#define IAX_COMMAND_PING 2
|
||||
#define IAX_COMMAND_PONG 3
|
||||
#define IAX_COMMAND_ACK 4
|
||||
#define IAX_COMMAND_HANGUP 5
|
||||
#define IAX_COMMAND_REJECT 6
|
||||
#define IAX_COMMAND_ACCEPT 7
|
||||
#define IAX_COMMAND_AUTHREQ 8
|
||||
#define IAX_COMMAND_AUTHREP 9
|
||||
#define IAX_COMMAND_INVAL 10
|
||||
#define IAX_COMMAND_LAGRQ 11
|
||||
#define IAX_COMMAND_LAGRP 12
|
||||
#define IAX_COMMAND_REGREQ 13 /* Registration request */
|
||||
#define IAX_COMMAND_REGAUTH 14 /* Registration authentication required */
|
||||
#define IAX_COMMAND_REGACK 15 /* Registration accepted */
|
||||
#define IAX_COMMAND_REGREJ 16 /* Registration rejected */
|
||||
#define IAX_COMMAND_REGREL 17 /* Force release of registration */
|
||||
#define IAX_COMMAND_VNAK 18 /* If we receive voice before valid first voice frame, send this */
|
||||
#define IAX_COMMAND_DPREQ 19 /* Request status of a dialplan entry */
|
||||
#define IAX_COMMAND_DPREP 20 /* Request status of a dialplan entry */
|
||||
#define IAX_COMMAND_DIAL 21 /* Request a dial on channel brought up TBD */
|
||||
#define IAX_COMMAND_TXREQ 22 /* Transfer Request */
|
||||
#define IAX_COMMAND_TXCNT 23 /* Transfer Connect */
|
||||
#define IAX_COMMAND_TXACC 24 /* Transfer Accepted */
|
||||
#define IAX_COMMAND_TXREADY 25 /* Transfer ready */
|
||||
#define IAX_COMMAND_TXREL 26 /* Transfer release */
|
||||
#define IAX_COMMAND_TXREJ 27 /* Transfer reject */
|
||||
#define IAX_COMMAND_QUELCH 28 /* Stop audio/video transmission */
|
||||
#define IAX_COMMAND_UNQUELCH 29 /* Resume audio/video transmission */
|
||||
#define IAX_COMMAND_POKE 30 /* Like ping, but does not require an open connection */
|
||||
#define IAX_COMMAND_PAGE 31 /* Paging description */
|
||||
#define IAX_COMMAND_MWI 32 /* Stand-alone message waiting indicator */
|
||||
#define IAX_COMMAND_UNSUPPORT 33 /* Unsupported message received */
|
||||
#define IAX_COMMAND_TRANSFER 34 /* Request remote transfer */
|
||||
#define IAX_COMMAND_PROVISION 35 /* Provision device */
|
||||
#define IAX_COMMAND_FWDOWNL 36 /* Download firmware */
|
||||
#define IAX_COMMAND_FWDATA 37 /* Firmware Data */
|
||||
|
||||
#define IAX_DEFAULT_REG_EXPIRE 60 /* By default require re-registration once per minute */
|
||||
|
||||
#define IAX_LINGER_TIMEOUT 10 /* How long to wait before closing bridged call */
|
||||
|
||||
#define IAX_DEFAULT_PORTNO 4569
|
||||
|
||||
/* IAX Information elements */
|
||||
#define IAX_IE_CALLED_NUMBER 1 /* Number/extension being called - string */
|
||||
#define IAX_IE_CALLING_NUMBER 2 /* Calling number - string */
|
||||
#define IAX_IE_CALLING_ANI 3 /* Calling number ANI for billing - string */
|
||||
#define IAX_IE_CALLING_NAME 4 /* Name of caller - string */
|
||||
#define IAX_IE_CALLED_CONTEXT 5 /* Context for number - string */
|
||||
#define IAX_IE_USERNAME 6 /* Username (peer or user) for authentication - string */
|
||||
#define IAX_IE_PASSWORD 7 /* Password for authentication - string */
|
||||
#define IAX_IE_CAPABILITY 8 /* Actual codec capability - unsigned int */
|
||||
#define IAX_IE_FORMAT 9 /* Desired codec format - unsigned int */
|
||||
#define IAX_IE_LANGUAGE 10 /* Desired language - string */
|
||||
#define IAX_IE_VERSION 11 /* Protocol version - short */
|
||||
#define IAX_IE_ADSICPE 12 /* CPE ADSI capability - short */
|
||||
#define IAX_IE_DNID 13 /* Originally dialed DNID - string */
|
||||
#define IAX_IE_AUTHMETHODS 14 /* Authentication method(s) - short */
|
||||
#define IAX_IE_CHALLENGE 15 /* Challenge data for MD5/RSA - string */
|
||||
#define IAX_IE_MD5_RESULT 16 /* MD5 challenge result - string */
|
||||
#define IAX_IE_RSA_RESULT 17 /* RSA challenge result - string */
|
||||
#define IAX_IE_APPARENT_ADDR 18 /* Apparent address of peer - struct sockaddr_in */
|
||||
#define IAX_IE_REFRESH 19 /* When to refresh registration - short */
|
||||
#define IAX_IE_DPSTATUS 20 /* Dialplan status - short */
|
||||
#define IAX_IE_CALLNO 21 /* Call number of peer - short */
|
||||
#define IAX_IE_CAUSE 22 /* Cause - string */
|
||||
#define IAX_IE_IAX_UNKNOWN 23 /* Unknown IAX command - byte */
|
||||
#define IAX_IE_MSGCOUNT 24 /* How many messages waiting - short */
|
||||
#define IAX_IE_AUTOANSWER 25 /* Request auto-answering -- none */
|
||||
#define IAX_IE_MUSICONHOLD 26 /* Request musiconhold with QUELCH -- none or string */
|
||||
#define IAX_IE_TRANSFERID 27 /* Transfer Request Identifier -- int */
|
||||
#define IAX_IE_RDNIS 28 /* Referring DNIS -- string */
|
||||
#define IAX_IE_PROVISIONING 29 /* Provisioning info */
|
||||
#define IAX_IE_AESPROVISIONING 30 /* AES Provisioning info */
|
||||
#define IAX_IE_DATETIME 31 /* Date/Time */
|
||||
#define IAX_IE_DEVICETYPE 32 /* Device Type -- string */
|
||||
#define IAX_IE_SERVICEIDENT 33 /* Service Identifier -- string */
|
||||
#define IAX_IE_FIRMWAREVER 34 /* Firmware revision -- u16 */
|
||||
#define IAX_IE_FWBLOCKDESC 35 /* Firmware block description -- u32 */
|
||||
#define IAX_IE_FWBLOCKDATA 36 /* Firmware block of data -- raw */
|
||||
#define IAX_IE_PROVVER 37 /* Provisioning Version (u32) */
|
||||
#define IAX_IE_CALLINGPRES 38 /* Calling presentation (u8) */
|
||||
#define IAX_IE_CALLINGTON 39 /* Calling type of number (u8) */
|
||||
#define IAX_IE_CALLINGTNS 40 /* Calling transit network select (u16) */
|
||||
#define IAX_IE_SAMPLINGRATE 41 /* Supported sampling rates (u16) */
|
||||
#define IAX_IE_CAUSECODE 42 /* Hangup cause (u8) */
|
||||
#define IAX_IE_ENCRYPTION 43 /* Encryption format (u16) */
|
||||
#define IAX_IE_ENCKEY 44 /* Encryption key (raw) */
|
||||
#define IAX_IE_CODEC_PREFS 45 /* Codec Negotiation */
|
||||
|
||||
#define IAX_IE_RR_JITTER 46 /* Received jitter (as in RFC1889) u32 */
|
||||
#define IAX_IE_RR_LOSS 47 /* Received loss (high byte loss pct, low 24 bits loss count, as in rfc1889 */
|
||||
#define IAX_IE_RR_PKTS 48 /* Received frames (total frames received) u32 */
|
||||
#define IAX_IE_RR_DELAY 49 /* Max playout delay for received frames (in ms) u16 */
|
||||
#define IAX_IE_RR_DROPPED 50 /* Dropped frames (presumably by jitterbuf) u32 */
|
||||
#define IAX_IE_RR_OOO 51 /* Frames received Out of Order u32 */
|
||||
|
||||
|
||||
|
||||
#define IAX_AUTH_PLAINTEXT (1 << 0)
|
||||
#define IAX_AUTH_MD5 (1 << 1)
|
||||
#define IAX_AUTH_RSA (1 << 2)
|
||||
|
||||
#define IAX_META_TRUNK 1 /* Trunk meta-message */
|
||||
#define IAX_META_VIDEO 2 /* Video frame */
|
||||
|
||||
#define IAX_RATE_8KHZ (1 << 0) /* 8khz sampling (default if absent) */
|
||||
#define IAX_RATE_11KHZ (1 << 1) /* 11.025khz sampling */
|
||||
#define IAX_RATE_16KHZ (1 << 2) /* 16khz sampling */
|
||||
#define IAX_RATE_22KHZ (1 << 3) /* 22.05khz sampling */
|
||||
#define IAX_RATE_44KHZ (1 << 4) /* 44.1khz sampling */
|
||||
#define IAX_RATE_48KHZ (1 << 5) /* 48khz sampling */
|
||||
|
||||
#define IAX_DPSTATUS_EXISTS (1 << 0)
|
||||
#define IAX_DPSTATUS_CANEXIST (1 << 1)
|
||||
#define IAX_DPSTATUS_NONEXISTANT (1 << 2)
|
||||
#define IAX_DPSTATUS_IGNOREPAT (1 << 14)
|
||||
#define IAX_DPSTATUS_MATCHMORE (1 << 15)
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma pack(push,1)
|
||||
#define __PACKED
|
||||
#else
|
||||
#define __PACKED __attribute__ ((__packed__))
|
||||
#endif
|
||||
|
||||
/* Full frames are always delivered reliably */
|
||||
struct ast_iax2_full_hdr {
|
||||
unsigned short scallno; /* Source call number -- high bit must be 1 */
|
||||
unsigned short dcallno; /* Destination call number -- high bit is 1 if retransmission */
|
||||
unsigned int ts; /* 32-bit timestamp in milliseconds (from 1st transmission) */
|
||||
unsigned char oseqno; /* Packet number (outgoing) */
|
||||
unsigned char iseqno; /* Packet number (next incoming expected) */
|
||||
char type; /* Frame type */
|
||||
unsigned char csub; /* Compressed subclass */
|
||||
unsigned char iedata[0];
|
||||
} __PACKED;
|
||||
|
||||
/* Mini header is used only for voice frames -- delivered unreliably */
|
||||
struct ast_iax2_mini_hdr {
|
||||
unsigned short callno; /* Source call number -- high bit must be 0, rest must be non-zero */
|
||||
unsigned short ts; /* 16-bit Timestamp (high 16 bits from last ast_iax2_full_hdr) */
|
||||
/* Frametype implicitly VOICE_FRAME */
|
||||
/* subclass implicit from last ast_iax2_full_hdr */
|
||||
unsigned char data[0];
|
||||
} __PACKED;
|
||||
|
||||
struct ast_iax2_meta_hdr {
|
||||
unsigned short zeros; /* Zeros field -- must be zero */
|
||||
unsigned char metacmd; /* Meta command */
|
||||
unsigned char cmddata; /* Command Data */
|
||||
unsigned char data[0];
|
||||
} __PACKED;
|
||||
|
||||
struct ast_iax2_video_hdr {
|
||||
unsigned short zeros; /* Zeros field -- must be zero */
|
||||
unsigned short callno; /* Video call number */
|
||||
unsigned short ts; /* Timestamp and mark if present */
|
||||
unsigned char data[0];
|
||||
} __PACKED;
|
||||
|
||||
struct ast_iax2_meta_trunk_hdr {
|
||||
unsigned int ts; /* 32-bit timestamp for all messages */
|
||||
unsigned char data[0];
|
||||
} __PACKED;
|
||||
|
||||
struct ast_iax2_meta_trunk_entry {
|
||||
unsigned short callno; /* Call number */
|
||||
unsigned short len; /* Length of data for this callno */
|
||||
} __PACKED;
|
||||
|
||||
#define IAX_FIRMWARE_MAGIC 0x69617879
|
||||
|
||||
struct ast_iax2_firmware_header {
|
||||
unsigned int magic; /* Magic number */
|
||||
unsigned short version; /* Software version */
|
||||
unsigned char devname[16]; /* Device */
|
||||
unsigned int datalen; /* Data length of file beyond header */
|
||||
unsigned char chksum[16]; /* Checksum of all data */
|
||||
unsigned char data[0];
|
||||
} __PACKED;
|
||||
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma pack(pop)
|
||||
#endif
|
||||
|
||||
#undef __PACKED
|
||||
|
||||
#endif
|
833
utils/iaxclient/lib/libiax2/src/jitterbuf.c
Normal file
833
utils/iaxclient/lib/libiax2/src/jitterbuf.c
Normal file
|
@ -0,0 +1,833 @@
|
|||
/*
|
||||
* jitterbuf: an application-independent jitterbuffer
|
||||
*
|
||||
* Copyrights:
|
||||
* Copyright (C) 2004-2005, Horizon Wimba, Inc.
|
||||
*
|
||||
* Contributors:
|
||||
* Steve Kann <stevek@stevek.com>
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU Lesser (Library) General Public License
|
||||
*
|
||||
* Copyright on this file is disclaimed to Digium for inclusion in Asterisk
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "jitterbuf.h"
|
||||
|
||||
/* define these here, just for ancient compiler systems */
|
||||
#define JB_LONGMAX 2147483647L
|
||||
#define JB_LONGMIN (-JB_LONGMAX - 1L)
|
||||
|
||||
/* MS VC can't do __VA_ARGS__ */
|
||||
#if (defined(WIN32) || defined(_WIN32_WCE)) && defined(_MSC_VER)
|
||||
#define jb_warn if (warnf) warnf
|
||||
#define jb_err if (errf) errf
|
||||
#define jb_dbg if (dbgf) dbgf
|
||||
|
||||
#ifdef DEEP_DEBUG
|
||||
#define jb_dbg2 if (dbgf) dbgf
|
||||
#else
|
||||
#define jb_dbg2 if (0) dbgf
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#define jb_warn(...) (warnf ? warnf(__VA_ARGS__) : (void)0)
|
||||
#define jb_err(...) (errf ? errf(__VA_ARGS__) : (void)0)
|
||||
#define jb_dbg(...) (dbgf ? dbgf(__VA_ARGS__) : (void)0)
|
||||
|
||||
#ifdef DEEP_DEBUG
|
||||
#define jb_dbg2(...) (dbgf ? dbgf(__VA_ARGS__) : (void)0)
|
||||
#else
|
||||
#define jb_dbg2(...) ((void)0)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
static jb_output_function_t warnf, errf, dbgf;
|
||||
|
||||
void jb_setoutput(jb_output_function_t err, jb_output_function_t warn, jb_output_function_t dbg)
|
||||
{
|
||||
errf = err;
|
||||
warnf = warn;
|
||||
dbgf = dbg;
|
||||
}
|
||||
|
||||
static void increment_losspct(jitterbuf *jb)
|
||||
{
|
||||
jb->info.losspct = (100000 + 499 * jb->info.losspct)/500;
|
||||
}
|
||||
|
||||
static void decrement_losspct(jitterbuf *jb)
|
||||
{
|
||||
jb->info.losspct = (499 * jb->info.losspct)/500;
|
||||
}
|
||||
|
||||
void jb_reset(jitterbuf *jb)
|
||||
{
|
||||
/* only save settings */
|
||||
jb_conf s = jb->info.conf;
|
||||
memset(jb, 0, sizeof(*jb));
|
||||
jb->info.conf = s;
|
||||
|
||||
/* initialize length, using the configured value */
|
||||
jb->info.current = jb->info.target = jb->info.conf.target_extra;
|
||||
jb->info.silence_begin_ts = -1;
|
||||
}
|
||||
|
||||
jitterbuf * jb_new()
|
||||
{
|
||||
jitterbuf *jb;
|
||||
|
||||
if (!(jb = (jitterbuf *)malloc(sizeof(*jb))))
|
||||
return NULL;
|
||||
|
||||
jb->info.conf.target_extra = JB_TARGET_EXTRA;
|
||||
|
||||
jb_reset(jb);
|
||||
|
||||
jb_dbg2("jb_new() = %x\n", jb);
|
||||
return jb;
|
||||
}
|
||||
|
||||
void jb_destroy(jitterbuf *jb)
|
||||
{
|
||||
jb_frame *frame;
|
||||
jb_dbg2("jb_destroy(%x)\n", jb);
|
||||
|
||||
/* free all the frames on the "free list" */
|
||||
frame = jb->free;
|
||||
while (frame != NULL) {
|
||||
jb_frame *next = frame->next;
|
||||
free(frame);
|
||||
frame = next;
|
||||
}
|
||||
|
||||
/* free ourselves! */
|
||||
free(jb);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#if 0
|
||||
static int longcmp(const void *a, const void *b)
|
||||
{
|
||||
return *(long *)a - *(long *)b;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* simple history manipulation */
|
||||
/* maybe later we can make the history buckets variable size, or something? */
|
||||
/* drop parameter determines whether we will drop outliers to minimize
|
||||
* delay */
|
||||
static int history_put(jitterbuf *jb, long ts, long now, long ms)
|
||||
{
|
||||
long delay = now - (ts - jb->info.resync_offset);
|
||||
long threshold = 2 * jb->info.jitter + jb->info.conf.resync_threshold;
|
||||
long kicked;
|
||||
|
||||
/* don't add special/negative times to history */
|
||||
if (ts <= 0)
|
||||
return 0;
|
||||
|
||||
/* check for drastic change in delay */
|
||||
if (jb->info.conf.resync_threshold != -1) {
|
||||
if (abs(delay - jb->info.last_delay) > threshold) {
|
||||
jb->info.cnt_delay_discont++;
|
||||
if (jb->info.cnt_delay_discont > 3) {
|
||||
/* resync the jitterbuffer */
|
||||
jb->info.cnt_delay_discont = 0;
|
||||
jb->hist_ptr = 0;
|
||||
jb->hist_maxbuf_valid = 0;
|
||||
|
||||
jb_warn("Resyncing the jb. last_delay %ld, this delay %ld, threshold %ld, new offset %ld\n", jb->info.last_delay, delay, threshold, ts - now);
|
||||
jb->info.resync_offset = ts - now;
|
||||
jb->info.last_delay = delay = 0; /* after resync, frame is right on time */
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
jb->info.last_delay = delay;
|
||||
jb->info.cnt_delay_discont = 0;
|
||||
}
|
||||
}
|
||||
|
||||
kicked = jb->history[jb->hist_ptr % JB_HISTORY_SZ];
|
||||
|
||||
jb->history[(jb->hist_ptr++) % JB_HISTORY_SZ] = delay;
|
||||
|
||||
/* optimization; the max/min buffers don't need to be recalculated,
|
||||
* if this packet's entry doesn't change them. This happens if this
|
||||
* packet is not involved, _and_ any packet that got kicked out of
|
||||
* the history is also not involved. We do a number of comparisons,
|
||||
* but it's probably still worthwhile, because it will usually
|
||||
* succeed, and should be a lot faster than going through all 500
|
||||
* packets in history */
|
||||
if (!jb->hist_maxbuf_valid)
|
||||
return 0;
|
||||
|
||||
/* don't do this until we've filled history
|
||||
* (reduces some edge cases below) */
|
||||
if (jb->hist_ptr < JB_HISTORY_SZ)
|
||||
goto invalidate;
|
||||
|
||||
/* if the new delay would go into min */
|
||||
if (delay < jb->hist_minbuf[JB_HISTORY_MAXBUF_SZ-1])
|
||||
goto invalidate;
|
||||
|
||||
/* or max.. */
|
||||
if (delay > jb->hist_maxbuf[JB_HISTORY_MAXBUF_SZ-1])
|
||||
goto invalidate;
|
||||
|
||||
/* or the kicked delay would be in min */
|
||||
if (kicked <= jb->hist_minbuf[JB_HISTORY_MAXBUF_SZ-1])
|
||||
goto invalidate;
|
||||
|
||||
if (kicked >= jb->hist_maxbuf[JB_HISTORY_MAXBUF_SZ-1])
|
||||
goto invalidate;
|
||||
|
||||
/* if we got here, we don't need to invalidate, 'cause this delay didn't
|
||||
* affect things */
|
||||
return 0;
|
||||
/* end optimization */
|
||||
|
||||
|
||||
invalidate:
|
||||
jb->hist_maxbuf_valid = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void history_calc_maxbuf(jitterbuf *jb)
|
||||
{
|
||||
int i,j;
|
||||
|
||||
if (jb->hist_ptr == 0)
|
||||
return;
|
||||
|
||||
|
||||
/* initialize maxbuf/minbuf to the latest value */
|
||||
for (i=0;i<JB_HISTORY_MAXBUF_SZ;i++) {
|
||||
/*
|
||||
* jb->hist_maxbuf[i] = jb->history[(jb->hist_ptr-1) % JB_HISTORY_SZ];
|
||||
* jb->hist_minbuf[i] = jb->history[(jb->hist_ptr-1) % JB_HISTORY_SZ];
|
||||
*/
|
||||
jb->hist_maxbuf[i] = JB_LONGMIN;
|
||||
jb->hist_minbuf[i] = JB_LONGMAX;
|
||||
}
|
||||
|
||||
/* use insertion sort to populate maxbuf */
|
||||
/* we want it to be the top "n" values, in order */
|
||||
|
||||
/* start at the beginning, or JB_HISTORY_SZ frames ago */
|
||||
i = (jb->hist_ptr > JB_HISTORY_SZ) ? (jb->hist_ptr - JB_HISTORY_SZ) : 0;
|
||||
|
||||
for (;i<jb->hist_ptr;i++) {
|
||||
long toins = jb->history[i % JB_HISTORY_SZ];
|
||||
|
||||
/* if the maxbuf should get this */
|
||||
if (toins > jb->hist_maxbuf[JB_HISTORY_MAXBUF_SZ-1]) {
|
||||
|
||||
/* insertion-sort it into the maxbuf */
|
||||
for (j=0;j<JB_HISTORY_MAXBUF_SZ;j++) {
|
||||
/* found where it fits */
|
||||
if (toins > jb->hist_maxbuf[j]) {
|
||||
/* move over */
|
||||
memmove(jb->hist_maxbuf + j + 1, jb->hist_maxbuf + j, (JB_HISTORY_MAXBUF_SZ - (j + 1)) * sizeof(jb->hist_maxbuf[0]));
|
||||
/* insert */
|
||||
jb->hist_maxbuf[j] = toins;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* if the minbuf should get this */
|
||||
if (toins < jb->hist_minbuf[JB_HISTORY_MAXBUF_SZ-1]) {
|
||||
|
||||
/* insertion-sort it into the maxbuf */
|
||||
for (j=0;j<JB_HISTORY_MAXBUF_SZ;j++) {
|
||||
/* found where it fits */
|
||||
if (toins < jb->hist_minbuf[j]) {
|
||||
/* move over */
|
||||
memmove(jb->hist_minbuf + j + 1, jb->hist_minbuf + j, (JB_HISTORY_MAXBUF_SZ - (j + 1)) * sizeof(jb->hist_minbuf[0]));
|
||||
/* insert */
|
||||
jb->hist_minbuf[j] = toins;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (0) {
|
||||
int k;
|
||||
fprintf(stderr, "toins = %ld\n", toins);
|
||||
fprintf(stderr, "maxbuf =");
|
||||
for (k=0;k<JB_HISTORY_MAXBUF_SZ;k++)
|
||||
fprintf(stderr, "%ld ", jb->hist_maxbuf[k]);
|
||||
fprintf(stderr, "\nminbuf =");
|
||||
for (k=0;k<JB_HISTORY_MAXBUF_SZ;k++)
|
||||
fprintf(stderr, "%ld ", jb->hist_minbuf[k]);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
jb->hist_maxbuf_valid = 1;
|
||||
}
|
||||
|
||||
static void history_get(jitterbuf *jb)
|
||||
{
|
||||
long max, min, jitter;
|
||||
int index;
|
||||
int count;
|
||||
|
||||
if (!jb->hist_maxbuf_valid)
|
||||
history_calc_maxbuf(jb);
|
||||
|
||||
/* count is how many items in history we're examining */
|
||||
count = (jb->hist_ptr < JB_HISTORY_SZ) ? jb->hist_ptr : JB_HISTORY_SZ;
|
||||
|
||||
/* index is the "n"ths highest/lowest that we'll look for */
|
||||
index = count * JB_HISTORY_DROPPCT / 100;
|
||||
|
||||
/* sanity checks for index */
|
||||
if (index > (JB_HISTORY_MAXBUF_SZ - 1))
|
||||
index = JB_HISTORY_MAXBUF_SZ - 1;
|
||||
|
||||
|
||||
if (index < 0) {
|
||||
jb->info.min = 0;
|
||||
jb->info.jitter = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
max = jb->hist_maxbuf[index];
|
||||
min = jb->hist_minbuf[index];
|
||||
|
||||
jitter = max - min;
|
||||
|
||||
/* these debug stmts compare the difference between looking at the absolute jitter, and the
|
||||
* values we get by throwing away the outliers */
|
||||
/*
|
||||
fprintf(stderr, "[%d] min=%d, max=%d, jitter=%d\n", index, min, max, jitter);
|
||||
fprintf(stderr, "[%d] min=%d, max=%d, jitter=%d\n", 0, jb->hist_minbuf[0], jb->hist_maxbuf[0], jb->hist_maxbuf[0]-jb->hist_minbuf[0]);
|
||||
*/
|
||||
|
||||
jb->info.min = min;
|
||||
jb->info.jitter = jitter;
|
||||
}
|
||||
|
||||
/* returns 1 if frame was inserted into head of queue, 0 otherwise */
|
||||
static int queue_put(jitterbuf *jb, void *data, const enum jb_frame_type type, long ms, long ts)
|
||||
{
|
||||
jb_frame *frame;
|
||||
jb_frame *p;
|
||||
int head = 0;
|
||||
long resync_ts = ts - jb->info.resync_offset;
|
||||
|
||||
if ((frame = jb->free)) {
|
||||
jb->free = frame->next;
|
||||
} else if (!(frame = (jb_frame *)malloc(sizeof(*frame)))) {
|
||||
jb_err("cannot allocate frame\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
jb->info.frames_cur++;
|
||||
|
||||
frame->data = data;
|
||||
frame->ts = resync_ts;
|
||||
frame->ms = ms;
|
||||
frame->type = type;
|
||||
|
||||
/*
|
||||
* frames are a circular list, jb-frames points to to the lowest ts,
|
||||
* jb->frames->prev points to the highest ts
|
||||
*/
|
||||
|
||||
if (!jb->frames) { /* queue is empty */
|
||||
jb->frames = frame;
|
||||
frame->next = frame;
|
||||
frame->prev = frame;
|
||||
head = 1;
|
||||
} else if (resync_ts < jb->frames->ts) {
|
||||
frame->next = jb->frames;
|
||||
frame->prev = jb->frames->prev;
|
||||
|
||||
frame->next->prev = frame;
|
||||
frame->prev->next = frame;
|
||||
|
||||
/* frame is out of order */
|
||||
jb->info.frames_ooo++;
|
||||
|
||||
jb->frames = frame;
|
||||
head = 1;
|
||||
} else {
|
||||
p = jb->frames;
|
||||
|
||||
/* frame is out of order */
|
||||
if (resync_ts < p->prev->ts) jb->info.frames_ooo++;
|
||||
|
||||
while (resync_ts < p->prev->ts && p->prev != jb->frames)
|
||||
p = p->prev;
|
||||
|
||||
frame->next = p;
|
||||
frame->prev = p->prev;
|
||||
|
||||
frame->next->prev = frame;
|
||||
frame->prev->next = frame;
|
||||
}
|
||||
return head;
|
||||
}
|
||||
|
||||
static long queue_next(jitterbuf *jb)
|
||||
{
|
||||
if (jb->frames)
|
||||
return jb->frames->ts;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
static long queue_last(jitterbuf *jb)
|
||||
{
|
||||
if (jb->frames)
|
||||
return jb->frames->prev->ts;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
static jb_frame *_queue_get(jitterbuf *jb, long ts, int all)
|
||||
{
|
||||
jb_frame *frame;
|
||||
frame = jb->frames;
|
||||
|
||||
if (!frame)
|
||||
return NULL;
|
||||
|
||||
/*jb_warn("queue_get: ASK %ld FIRST %ld\n", ts, frame->ts); */
|
||||
|
||||
if (all || ts >= frame->ts) {
|
||||
/* remove this frame */
|
||||
frame->prev->next = frame->next;
|
||||
frame->next->prev = frame->prev;
|
||||
|
||||
if (frame->next == frame)
|
||||
jb->frames = NULL;
|
||||
else
|
||||
jb->frames = frame->next;
|
||||
|
||||
|
||||
/* insert onto "free" single-linked list */
|
||||
frame->next = jb->free;
|
||||
jb->free = frame;
|
||||
|
||||
jb->info.frames_cur--;
|
||||
|
||||
/* we return the frame pointer, even though it's on free list,
|
||||
* but caller must copy data */
|
||||
return frame;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static jb_frame *queue_get(jitterbuf *jb, long ts)
|
||||
{
|
||||
return _queue_get(jb,ts,0);
|
||||
}
|
||||
|
||||
static jb_frame *queue_getall(jitterbuf *jb)
|
||||
{
|
||||
return _queue_get(jb,0,1);
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* some diagnostics */
|
||||
static void jb_dbginfo(jitterbuf *jb)
|
||||
{
|
||||
if (dbgf == NULL)
|
||||
return;
|
||||
|
||||
jb_dbg("\njb info: fin=%ld fout=%ld flate=%ld flost=%ld fdrop=%ld fcur=%ld\n",
|
||||
jb->info.frames_in, jb->info.frames_out, jb->info.frames_late, jb->info.frames_lost, jb->info.frames_dropped, jb->info.frames_cur);
|
||||
|
||||
jb_dbg("jitter=%ld current=%ld target=%ld min=%ld sil=%d len=%d len/fcur=%ld\n",
|
||||
jb->info.jitter, jb->info.current, jb->info.target, jb->info.min, jb->info.silence_begin_ts, jb->info.current - jb->info.min,
|
||||
jb->info.frames_cur ? (jb->info.current - jb->info.min)/jb->info.frames_cur : -8);
|
||||
if (jb->info.frames_in > 0)
|
||||
jb_dbg("jb info: Loss PCT = %ld%%, Late PCT = %ld%%\n",
|
||||
jb->info.frames_lost * 100/(jb->info.frames_in + jb->info.frames_lost),
|
||||
jb->info.frames_late * 100/jb->info.frames_in);
|
||||
jb_dbg("jb info: queue %d -> %d. last_ts %d (queue len: %d) last_ms %d\n",
|
||||
queue_next(jb),
|
||||
queue_last(jb),
|
||||
jb->info.next_voice_ts,
|
||||
queue_last(jb) - queue_next(jb),
|
||||
jb->info.last_voice_ms);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef DEEP_DEBUG
|
||||
static void jb_chkqueue(jitterbuf *jb)
|
||||
{
|
||||
int i=0;
|
||||
jb_frame *p = jb->frames;
|
||||
|
||||
if (!p) {
|
||||
return;
|
||||
}
|
||||
|
||||
do {
|
||||
if (p->next == NULL) {
|
||||
jb_err("Queue is BROKEN at item [%d]", i);
|
||||
}
|
||||
i++;
|
||||
p=p->next;
|
||||
} while (p->next != jb->frames);
|
||||
}
|
||||
|
||||
static void jb_dbgqueue(jitterbuf *jb)
|
||||
{
|
||||
int i=0;
|
||||
jb_frame *p = jb->frames;
|
||||
|
||||
jb_dbg("queue: ");
|
||||
|
||||
if (!p) {
|
||||
jb_dbg("EMPTY\n");
|
||||
return;
|
||||
}
|
||||
|
||||
do {
|
||||
jb_dbg("[%d]=%ld ", i++, p->ts);
|
||||
p=p->next;
|
||||
} while (p->next != jb->frames);
|
||||
|
||||
jb_dbg("\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
enum jb_return_code jb_put(jitterbuf *jb, void *data, const enum jb_frame_type type, long ms, long ts, long now)
|
||||
{
|
||||
jb_dbg2("jb_put(%x,%x,%ld,%ld,%ld)\n", jb, data, ms, ts, now);
|
||||
|
||||
jb->info.frames_in++;
|
||||
|
||||
if (type == JB_TYPE_VOICE) {
|
||||
/* presently, I'm only adding VOICE frames to history and drift
|
||||
* calculations; mostly because with the IAX integrations, I'm
|
||||
* sending retransmitted control frames with their awkward
|
||||
* timestamps through
|
||||
*/
|
||||
if (history_put(jb,ts,now,ms))
|
||||
return JB_DROP;
|
||||
}
|
||||
|
||||
/* if put into head of queue, caller needs to reschedule */
|
||||
if (queue_put(jb,data,type,ms,ts)) {
|
||||
return JB_SCHED;
|
||||
}
|
||||
|
||||
return JB_OK;
|
||||
}
|
||||
|
||||
|
||||
static enum jb_return_code _jb_get(jitterbuf *jb, jb_frame *frameout, long now, long interpl)
|
||||
{
|
||||
jb_frame *frame;
|
||||
long diff;
|
||||
|
||||
/*if ((now - jb_next(jb)) > 2 * jb->info.last_voice_ms) jb_warn("SCHED: %ld", (now - jb_next(jb))); */
|
||||
/* get jitter info */
|
||||
history_get(jb);
|
||||
|
||||
|
||||
/* target */
|
||||
jb->info.target = jb->info.jitter + jb->info.min + jb->info.conf.target_extra;
|
||||
|
||||
/* if a hard clamp was requested, use it */
|
||||
if ((jb->info.conf.max_jitterbuf) && ((jb->info.target - jb->info.min) > jb->info.conf.max_jitterbuf)) {
|
||||
jb_dbg("clamping target from %d to %d\n", (jb->info.target - jb->info.min), jb->info.conf.max_jitterbuf);
|
||||
jb->info.target = jb->info.min + jb->info.conf.max_jitterbuf;
|
||||
}
|
||||
|
||||
diff = jb->info.target - jb->info.current;
|
||||
|
||||
/* jb_warn("diff = %d lms=%d last = %d now = %d\n", diff, */
|
||||
/* jb->info.last_voice_ms, jb->info.last_adjustment, now); */
|
||||
|
||||
/* let's work on non-silent case first */
|
||||
if (!jb->info.silence_begin_ts) {
|
||||
/* we want to grow */
|
||||
if ((diff > 0) &&
|
||||
/* we haven't grown in the delay length */
|
||||
(((jb->info.last_adjustment + JB_ADJUST_DELAY) < now) ||
|
||||
/* we need to grow more than the "length" we have left */
|
||||
(diff > queue_last(jb) - queue_next(jb)) ) ) {
|
||||
/* grow by interp frame length */
|
||||
jb->info.current += interpl;
|
||||
jb->info.next_voice_ts += interpl;
|
||||
jb->info.last_voice_ms = interpl;
|
||||
jb->info.last_adjustment = now;
|
||||
jb->info.cnt_contig_interp++;
|
||||
/* assume silence instead of continuing to interpolate */
|
||||
if (jb->info.conf.max_contig_interp && jb->info.cnt_contig_interp >= jb->info.conf.max_contig_interp) {
|
||||
jb->info.silence_begin_ts = jb->info.next_voice_ts - jb->info.current;
|
||||
}
|
||||
jb_dbg("G");
|
||||
return JB_INTERP;
|
||||
}
|
||||
|
||||
frame = queue_get(jb, jb->info.next_voice_ts - jb->info.current);
|
||||
|
||||
/* not a voice frame; just return it. */
|
||||
if (frame && frame->type != JB_TYPE_VOICE) {
|
||||
/* track start of silence */
|
||||
if (frame->type == JB_TYPE_SILENCE) {
|
||||
jb->info.silence_begin_ts = frame->ts;
|
||||
jb->info.cnt_contig_interp = 0;
|
||||
}
|
||||
|
||||
*frameout = *frame;
|
||||
jb->info.frames_out++;
|
||||
jb_dbg("o");
|
||||
return JB_OK;
|
||||
}
|
||||
|
||||
/* voice frame is later than expected */
|
||||
if (frame && frame->ts + jb->info.current < jb->info.next_voice_ts) {
|
||||
if (frame->ts + jb->info.current > jb->info.next_voice_ts - jb->info.last_voice_ms) {
|
||||
/* either we interpolated past this frame in the last jb_get */
|
||||
/* or the frame is still in order, but came a little too quick */
|
||||
*frameout = *frame;
|
||||
/* reset expectation for next frame */
|
||||
jb->info.next_voice_ts = frame->ts + jb->info.current + frame->ms;
|
||||
jb->info.frames_out++;
|
||||
decrement_losspct(jb);
|
||||
jb->info.cnt_contig_interp = 0;
|
||||
jb_dbg("v");
|
||||
return JB_OK;
|
||||
} else {
|
||||
/* voice frame is late */
|
||||
*frameout = *frame;
|
||||
jb->info.frames_out++;
|
||||
decrement_losspct(jb);
|
||||
jb->info.frames_late++;
|
||||
jb->info.frames_lost--;
|
||||
jb_dbg("l");
|
||||
/*jb_warn("\nlate: wanted=%ld, this=%ld, next=%ld\n", jb->info.next_voice_ts - jb->info.current, frame->ts, queue_next(jb));
|
||||
jb_warninfo(jb); */
|
||||
return JB_DROP;
|
||||
}
|
||||
}
|
||||
|
||||
/* keep track of frame sizes, to allow for variable sized-frames */
|
||||
if (frame && frame->ms > 0) {
|
||||
jb->info.last_voice_ms = frame->ms;
|
||||
}
|
||||
|
||||
/* we want to shrink; shrink at 1 frame / 500ms */
|
||||
/* unless we don't have a frame, then shrink 1 frame */
|
||||
/* every 80ms (though perhaps we can shrink even faster */
|
||||
/* in this case) */
|
||||
if (diff < -jb->info.conf.target_extra &&
|
||||
((!frame && jb->info.last_adjustment + 80 < now) ||
|
||||
(jb->info.last_adjustment + 500 < now))) {
|
||||
|
||||
jb->info.last_adjustment = now;
|
||||
jb->info.cnt_contig_interp = 0;
|
||||
|
||||
if (frame) {
|
||||
*frameout = *frame;
|
||||
/* shrink by frame size we're throwing out */
|
||||
jb->info.current -= frame->ms;
|
||||
jb->info.frames_out++;
|
||||
decrement_losspct(jb);
|
||||
jb->info.frames_dropped++;
|
||||
jb_dbg("s");
|
||||
return JB_DROP;
|
||||
} else {
|
||||
/* shrink by last_voice_ms */
|
||||
jb->info.current -= jb->info.last_voice_ms;
|
||||
jb->info.frames_lost++;
|
||||
increment_losspct(jb);
|
||||
jb_dbg("S");
|
||||
return JB_NOFRAME;
|
||||
}
|
||||
}
|
||||
|
||||
/* lost frame */
|
||||
if (!frame) {
|
||||
/* this is a bit of a hack for now, but if we're close to
|
||||
* target, and we find a missing frame, it makes sense to
|
||||
* grow, because the frame might just be a bit late;
|
||||
* otherwise, we presently get into a pattern where we return
|
||||
* INTERP for the lost frame, then it shows up next, and we
|
||||
* throw it away because it's late */
|
||||
/* I've recently only been able to replicate this using
|
||||
* iaxclient talking to app_echo on asterisk. In this case,
|
||||
* my outgoing packets go through asterisk's (old)
|
||||
* jitterbuffer, and then might get an unusual increasing delay
|
||||
* there if it decides to grow?? */
|
||||
/* Update: that might have been a different bug, that has been fixed..
|
||||
* But, this still seemed like a good idea, except that it ended up making a single actual
|
||||
* lost frame get interpolated two or more times, when there was "room" to grow, so it might
|
||||
* be a bit of a bad idea overall */
|
||||
/*if (diff > -1 * jb->info.last_voice_ms) {
|
||||
jb->info.current += jb->info.last_voice_ms;
|
||||
jb->info.last_adjustment = now;
|
||||
jb_warn("g");
|
||||
return JB_INTERP;
|
||||
} */
|
||||
jb->info.frames_lost++;
|
||||
increment_losspct(jb);
|
||||
jb->info.next_voice_ts += interpl;
|
||||
jb->info.last_voice_ms = interpl;
|
||||
jb->info.cnt_contig_interp++;
|
||||
/* assume silence instead of continuing to interpolate */
|
||||
if (jb->info.conf.max_contig_interp && jb->info.cnt_contig_interp >= jb->info.conf.max_contig_interp) {
|
||||
jb->info.silence_begin_ts = jb->info.next_voice_ts - jb->info.current;
|
||||
}
|
||||
jb_dbg("L");
|
||||
return JB_INTERP;
|
||||
}
|
||||
|
||||
/* normal case; return the frame, increment stuff */
|
||||
*frameout = *frame;
|
||||
jb->info.next_voice_ts += frame->ms;
|
||||
jb->info.frames_out++;
|
||||
jb->info.cnt_contig_interp = 0;
|
||||
decrement_losspct(jb);
|
||||
jb_dbg("v");
|
||||
return JB_OK;
|
||||
} else {
|
||||
/* TODO: after we get the non-silent case down, we'll make the
|
||||
* silent case -- basically, we'll just grow and shrink faster
|
||||
* here, plus handle next_voice_ts a bit differently */
|
||||
|
||||
/* to disable silent special case altogether, just uncomment this: */
|
||||
/* jb->info.silence_begin_ts = 0; */
|
||||
|
||||
/* shrink interpl len every 10ms during silence */
|
||||
if (diff < -jb->info.conf.target_extra &&
|
||||
jb->info.last_adjustment + 10 <= now) {
|
||||
jb->info.current -= interpl;
|
||||
jb->info.last_adjustment = now;
|
||||
}
|
||||
|
||||
frame = queue_get(jb, now - jb->info.current);
|
||||
if (!frame) {
|
||||
return JB_NOFRAME;
|
||||
} else if (frame->type != JB_TYPE_VOICE) {
|
||||
/* normal case; in silent mode, got a non-voice frame */
|
||||
*frameout = *frame;
|
||||
jb->info.frames_out++;
|
||||
return JB_OK;
|
||||
}
|
||||
if (frame->ts < jb->info.silence_begin_ts) {
|
||||
/* voice frame is late */
|
||||
*frameout = *frame;
|
||||
jb->info.frames_out++;
|
||||
decrement_losspct(jb);
|
||||
jb->info.frames_late++;
|
||||
jb->info.frames_lost--;
|
||||
jb_dbg("l");
|
||||
/*jb_warn("\nlate: wanted=%ld, this=%ld, next=%ld\n", jb->info.next_voice_ts - jb->info.current, frame->ts, queue_next(jb));
|
||||
jb_warninfo(jb); */
|
||||
return JB_DROP;
|
||||
} else {
|
||||
/* voice frame */
|
||||
/* try setting current to target right away here */
|
||||
jb->info.current = jb->info.target;
|
||||
jb->info.silence_begin_ts = 0;
|
||||
jb->info.next_voice_ts = frame->ts + jb->info.current + frame->ms;
|
||||
jb->info.last_voice_ms = frame->ms;
|
||||
jb->info.frames_out++;
|
||||
decrement_losspct(jb);
|
||||
*frameout = *frame;
|
||||
jb_dbg("V");
|
||||
return JB_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
long jb_next(jitterbuf *jb)
|
||||
{
|
||||
if (jb->info.silence_begin_ts) {
|
||||
if (jb->frames) {
|
||||
long next = queue_next(jb);
|
||||
history_get(jb);
|
||||
/* shrink during silence */
|
||||
if (jb->info.target - jb->info.current < -jb->info.conf.target_extra)
|
||||
return jb->info.last_adjustment + 10;
|
||||
return next + jb->info.target;
|
||||
}
|
||||
else
|
||||
return JB_LONGMAX;
|
||||
} else {
|
||||
return jb->info.next_voice_ts;
|
||||
}
|
||||
}
|
||||
|
||||
enum jb_return_code jb_get(jitterbuf *jb, jb_frame *frameout, long now, long interpl)
|
||||
{
|
||||
enum jb_return_code ret = _jb_get(jb, frameout, now, interpl);
|
||||
#if 0
|
||||
static int lastts=0;
|
||||
int thists = ((ret == JB_OK) || (ret == JB_DROP)) ? frameout->ts : 0;
|
||||
jb_warn("jb_get(%x,%x,%ld) = %d (%d)\n", jb, frameout, now, ret, thists);
|
||||
if (thists && thists < lastts) jb_warn("XXXX timestamp roll-back!!!\n");
|
||||
lastts = thists;
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
enum jb_return_code jb_getall(jitterbuf *jb, jb_frame *frameout)
|
||||
{
|
||||
jb_frame *frame;
|
||||
frame = queue_getall(jb);
|
||||
|
||||
if (!frame) {
|
||||
return JB_NOFRAME;
|
||||
}
|
||||
|
||||
*frameout = *frame;
|
||||
return JB_OK;
|
||||
}
|
||||
|
||||
|
||||
enum jb_return_code jb_getinfo(jitterbuf *jb, jb_info *stats)
|
||||
{
|
||||
history_get(jb);
|
||||
|
||||
*stats = jb->info;
|
||||
|
||||
return JB_OK;
|
||||
}
|
||||
|
||||
enum jb_return_code jb_setconf(jitterbuf *jb, jb_conf *conf)
|
||||
{
|
||||
/* take selected settings from the struct */
|
||||
|
||||
jb->info.conf.max_jitterbuf = conf->max_jitterbuf;
|
||||
jb->info.conf.resync_threshold = conf->resync_threshold;
|
||||
jb->info.conf.max_contig_interp = conf->max_contig_interp;
|
||||
|
||||
/* -1 indicates use of the default JB_TARGET_EXTRA value */
|
||||
jb->info.conf.target_extra = ( conf->target_extra == -1 )
|
||||
? JB_TARGET_EXTRA
|
||||
: conf->target_extra
|
||||
;
|
||||
|
||||
/* update these to match new target_extra setting */
|
||||
jb->info.current = jb->info.conf.target_extra;
|
||||
jb->info.target = jb->info.conf.target_extra;
|
||||
|
||||
return JB_OK;
|
||||
}
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue