Compare commits
3
Commits
405483a00d
..
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f0a880c64d | ||
|
|
03c58c4572 | ||
|
|
c8d9bad845 |
@@ -434,6 +434,13 @@ Codec::Info OpusCodec::info()
|
||||
};
|
||||
}
|
||||
|
||||
int OpusCodec::packetTime(std::span<const uint8_t> payload)
|
||||
{
|
||||
int samples = payload.empty() ? 0
|
||||
: opus_packet_get_nb_samples(payload.data(), (opus_int32)payload.size(), mSamplerate);
|
||||
return samples > 0 ? samples * 1000 / mSamplerate : frameTime();
|
||||
}
|
||||
|
||||
Codec::EncodeResult OpusCodec::encode(std::span<const uint8_t> input, std::span<uint8_t> output)
|
||||
{
|
||||
// opus_encode() takes the frame size in samples per channel and the output
|
||||
@@ -1132,13 +1139,15 @@ G722Codec::~G722Codec()
|
||||
|
||||
Codec::Info G722Codec::info()
|
||||
{
|
||||
// ToDo: double check the G722 calls - remember RFC has bug about samplerate
|
||||
// G.722 decodes to 16 kHz (640 bytes of PCM per 20 ms frame), but RFC 3551 keeps its RTP
|
||||
// clock at 8 kHz for historical reasons: the timestamp unit is 1/8000, not 1/samplerate.
|
||||
return {.mName = G722_MIME_NAME,
|
||||
.mSamplerate = 8000,
|
||||
.mSamplerate = 16000,
|
||||
.mChannels = 1,
|
||||
.mPcmLength = 640,
|
||||
.mFrameTime = 20,
|
||||
.mRtpLength = 160};
|
||||
.mRtpLength = 160,
|
||||
.mTimestampUnit = 1.0f / 8000};
|
||||
}
|
||||
|
||||
Codec::EncodeResult G722Codec::encode(std::span<const uint8_t> input, std::span<uint8_t> output)
|
||||
@@ -1186,7 +1195,8 @@ const char* G722Codec::G722Factory::name()
|
||||
|
||||
int G722Codec::G722Factory::samplerate()
|
||||
{
|
||||
// Although G722 uses 16000 as rate for timestamping RTP frames - in fact it is 8KHz codec. So return 8KHz here.
|
||||
// The rate SDP advertises (rtpmap G722/8000) is the RTP clock, 8 kHz by RFC 3551, although the
|
||||
// audio is 16 kHz; see G722Codec::info().
|
||||
return 8000;
|
||||
}
|
||||
|
||||
|
||||
@@ -69,6 +69,8 @@ protected:
|
||||
int mDecoderChannels = 0;
|
||||
|
||||
public:
|
||||
int packetTime(std::span<const uint8_t> payload) override;
|
||||
|
||||
struct Params
|
||||
{
|
||||
bool mUseDtx = false, mUseInbandFec = false, mStereo = false;
|
||||
|
||||
@@ -520,13 +520,11 @@ Codec* AudioReceiver::add(const std::shared_ptr<jrtplib::RTPPacket>& p)
|
||||
|
||||
if (!codec)
|
||||
time_length = 10;
|
||||
else if (!codec->rtpLength())
|
||||
time_length = codec->frameTime();
|
||||
else
|
||||
time_length = lround(double(payloadLength) / codec->rtpLength() * codec->frameTime());
|
||||
time_length = codec->packetTime(std::span{p->GetPayloadData(), (size_t)payloadLength});
|
||||
|
||||
if (codec)
|
||||
samplerate = codec->samplerate();
|
||||
samplerate = codec->rtpClockRate(); // RTP timestamp units, not PCM rate (G.722)
|
||||
}
|
||||
|
||||
// Process jitter anyway - can we decode payload or not
|
||||
@@ -724,7 +722,7 @@ AudioReceiver::DecodeResult AudioReceiver::decodePacketTo(Audio::DataWindow& out
|
||||
if (mLastPacketTimestamp && mLastPacketTimeLength && mCodec)
|
||||
{
|
||||
int units = rtp.GetTimestamp() - *mLastPacketTimestamp;
|
||||
int milliseconds = units / (mCodec->samplerate() / 1000);
|
||||
int milliseconds = units / (mCodec->rtpClockRate() / 1000);
|
||||
if (milliseconds > mLastPacketTimeLength)
|
||||
{
|
||||
auto silenceLength = std::chrono::milliseconds(milliseconds - mLastPacketTimeLength);
|
||||
@@ -794,8 +792,11 @@ AudioReceiver::DecodeResult AudioReceiver::decodePacketTo(Audio::DataWindow& out
|
||||
mFrameCount = mCodec->rtpLength() ? rtp.GetPayloadLength() / mCodec->rtpLength() : 1;
|
||||
int frameLength = mCodec->rtpLength() ? mCodec->rtpLength() : (int)rtp.GetPayloadLength();
|
||||
|
||||
// Save last packet time length
|
||||
mLastPacketTimeLength = mFrameCount * mCodec->frameTime();
|
||||
// Save last packet time length. Taken from the payload, not mFrameCount *
|
||||
// frameTime(): an Opus packet of 40 or 60 ms is one "frame" here, and counting
|
||||
// it as frameTime() (20 ms) made the gap check above emit silence before every
|
||||
// packet and pushed the jitter buffer into discarding about half of them.
|
||||
mLastPacketTimeLength = mCodec->packetTime(std::span{rtp.GetPayloadData(), payload_length});
|
||||
|
||||
// Decode
|
||||
for (int i = 0; i < mFrameCount && !mCodecSettings.mSkipDecode; i++)
|
||||
@@ -1157,12 +1158,17 @@ AudioReceiver::MediaInfo AudioReceiver::infoFor(jrtplib::RTPPacket& p)
|
||||
|
||||
if (codec->rtpLength() != 0)
|
||||
{
|
||||
int frameCount = static_cast<int>(p.GetPayloadLength() / codec->rtpLength());
|
||||
if (p.GetPayloadType() == 9 /*G729A silence*/ && p.GetPayloadLength() % codec->rtpLength())
|
||||
frameCount++;
|
||||
|
||||
// A G.729 (PT 18) SID frame is shorter than a voice frame but stands for one; other
|
||||
// codecs scale with the payload (G.722 at 10 ms ptime carries half a 160-byte frame).
|
||||
if (p.GetPayloadType() == 18 && p.GetPayloadLength() % codec->rtpLength())
|
||||
{
|
||||
int frameCount = static_cast<int>(p.GetPayloadLength() / codec->rtpLength()) + 1;
|
||||
packetTime = std::chrono::milliseconds(frameCount * codec->frameTime());
|
||||
}
|
||||
else
|
||||
packetTime = std::chrono::milliseconds(
|
||||
lround(double(p.GetPayloadLength()) / codec->rtpLength() * codec->frameTime()));
|
||||
}
|
||||
else if (typeid(*codec) == typeid(OpusCodec))
|
||||
{
|
||||
OpusCodec* oc = dynamic_cast<OpusCodec*>(codec);
|
||||
|
||||
@@ -114,7 +114,7 @@ void AudioStream::setTransmittingCodec(Codec::Factory& factory, int payloadType)
|
||||
mTransmittingCodec = factory.create();
|
||||
mTransmittingPayloadType = payloadType;
|
||||
if (mRtpSession.IsActive())
|
||||
mRtpSession.SetTimestampUnit(1.0 / mTransmittingCodec->samplerate());
|
||||
mRtpSession.SetTimestampUnit(mTransmittingCodec->timestampUnit());
|
||||
}
|
||||
|
||||
PCodec AudioStream::transmittingCodec()
|
||||
@@ -241,7 +241,7 @@ void AudioStream::addData(const void* buffer, int bytes)
|
||||
ICELogMedia(<< "Sending RTP packet pt = " << mTransmittingPayloadType
|
||||
<< ", plength = " << (int)mEncodedAudio.size() << " to ");
|
||||
mRtpSession.SendPacketEx(mEncodedAudio.data(), mEncodedAudio.size(), mTransmittingPayloadType, false,
|
||||
packetTime * codec->samplerate() / 1000, 0, nullptr, 0);
|
||||
packetTime * codec->rtpClockRate() / 1000, 0, nullptr, 0);
|
||||
mEncodedAudio.clear();
|
||||
encodedTime = 0;
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#ifndef __MT_CODEC_H
|
||||
#define __MT_CODEC_H
|
||||
|
||||
#include <cmath>
|
||||
#include <map>
|
||||
#include <span>
|
||||
|
||||
@@ -66,9 +67,24 @@ public:
|
||||
int frameTime() { return info().mFrameTime; }
|
||||
std::string name() { return info().mName; }
|
||||
float timestampUnit() { return info().mTimestampUnit == 0.0f ? 1.0f / info().mSamplerate : info().mTimestampUnit; }
|
||||
// RTP clock rate in Hz, the unit of RTP timestamps. Equals samplerate() except for codecs
|
||||
// whose RTP clock differs from the decoded audio: G.722 decodes to 16 kHz but its RTP clock
|
||||
// is 8 kHz (RFC 3551). Use it for timestamp arithmetic and jitter, samplerate() for PCM.
|
||||
int rtpClockRate() { return static_cast<int>(1.0f / timestampUnit() + 0.5f); }
|
||||
|
||||
Audio::Format getAudioFormat() { return Audio::Format(this->info().mSamplerate, this->info().mChannels); }
|
||||
|
||||
// Audio duration of one RTP payload, in milliseconds. The default suits fixed-size
|
||||
// frames (rtpLength() bytes per frameTime()); a codec whose packets carry a variable
|
||||
// amount of audio (Opus: 2.5-120 ms, whatever the sender's ptime) reads it from the
|
||||
// payload instead, as frameTime() is only the local ptime.
|
||||
virtual int packetTime(std::span<const uint8_t> payload)
|
||||
{
|
||||
if (!rtpLength())
|
||||
return frameTime();
|
||||
return static_cast<int>(std::lround(double(payload.size()) / rtpLength() * frameTime()));
|
||||
}
|
||||
|
||||
// Returns size of encoded data (RTP) in bytes
|
||||
struct EncodeResult
|
||||
{
|
||||
|
||||
@@ -1,16 +1,13 @@
|
||||
project (g722_codec)
|
||||
|
||||
# Rely on C++ 11
|
||||
set (CMAKE_CXX_STANDARD 20)
|
||||
set (CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||
|
||||
# G.722 from Asterisk (codecs/g722): Steve Underwood's spandsp code, which he
|
||||
# placed in the public domain, on top of the CMU 1993 codec, whose use "for
|
||||
# any research or commercial purpose, is completely unrestricted". See README.md.
|
||||
set (G722_SOURCES
|
||||
g722_bitstream.c
|
||||
g722_decode.c
|
||||
g722_encode.c
|
||||
)
|
||||
|
||||
add_library(g722_codec ${G722_SOURCES})
|
||||
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
# G.722 codec
|
||||
|
||||
Source: Asterisk, `codecs/g722/` (`g722.h`, `g722_encode.c`, `g722_decode.c`),
|
||||
https://github.com/asterisk/asterisk, taken 2026-09-21.
|
||||
|
||||
## Licence
|
||||
|
||||
No copyleft. The code has two layers:
|
||||
|
||||
- **Steve Underwood, 2005** (spandsp): "Despite my general liking of the GPL, I
|
||||
place my own contributions to this code in the public domain for the benefit
|
||||
of all mankind - even the slimy ones who might try to proprietize my work and
|
||||
use it to my detriment." (in each file's header)
|
||||
- **Carnegie Mellon University, 1993** (Chengxiang Lu and Alex Hauptmann, Speech
|
||||
Group): "The Carnegie Mellon ADPCM program is Copyright (c) 1993 by Carnegie
|
||||
Mellon University. Use of this program, for any research or commercial
|
||||
purpose, is completely unrestricted. If you make use of or redistribute this
|
||||
material, we would appreciate acknowlegement of its origin." (the terms as
|
||||
reproduced in sippy's libg722, https://github.com/sippy/libg722, LICENSE)
|
||||
|
||||
This replaces an older copy of the same spandsp code that was offered only
|
||||
under GPL-2 or LGPL-2.1.
|
||||
|
||||
## Behaviour
|
||||
|
||||
Asterisk's version maps 16-bit PCM to the codec's range: the encoder halves its
|
||||
input and the decoder doubles its output. Streams from Asterisk and ffmpeg
|
||||
therefore decode at their original level. The older copy did neither, so it
|
||||
decoded those streams 6 dB too quiet and clipped encoder input above -6 dBFS.
|
||||
|
||||
Local changes:
|
||||
- the decoder saturates its output (`saturate()`) instead of casting. Asterisk's
|
||||
cast wraps loud samples around int16: 259 samples in 11 s of speech peaking
|
||||
at -0.2 dBFS came out as large values of the opposite sign;
|
||||
- `g722.h` includes `<stdint.h>` and maps `__inline__` to `__inline` for MSVC.
|
||||
+22
-53
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* VoIPcodecs - a series of DSP components for telephony
|
||||
* SpanDSP - a series of DSP components for telephony
|
||||
*
|
||||
* g722.h - The ITU G.722 codec.
|
||||
*
|
||||
@@ -7,21 +7,10 @@
|
||||
*
|
||||
* Copyright (C) 2005 Steve Underwood
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2, or
|
||||
* the Lesser GNU General Public License version 2.1, as published by
|
||||
* the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
* Despite my general liking of the GPL, I place my own contributions
|
||||
* to this code in the public domain for the benefit of all mankind -
|
||||
* even the slimy ones who might try to proprietize my work and use it
|
||||
* to my detriment.
|
||||
*
|
||||
* Based on a single channel G.722 codec which is:
|
||||
*
|
||||
@@ -29,17 +18,19 @@
|
||||
* Computer Science, Speech Group
|
||||
* Chengxiang Lu and Alex Hauptmann
|
||||
*
|
||||
* $Id: g722.h,v 1.17 2008/02/09 15:32:26 steveu Exp $
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
|
||||
/*! \file */
|
||||
|
||||
#if !defined(_SPANDSP_G722_H_)
|
||||
#define _SPANDSP_G722_H_
|
||||
|
||||
#include "inttypes.h"
|
||||
#if !defined(_G722_H_)
|
||||
#define _G722_H_
|
||||
|
||||
#include <stdint.h> /* rtphone: the header uses int16_t/uint8_t itself */
|
||||
#if defined(_MSC_VER) && !defined(__inline__)
|
||||
#define __inline__ __inline /* rtphone: MSVC has no __inline__ (the .c files use it) */
|
||||
#endif
|
||||
|
||||
/*! \page g722_page G.722 encoding and decoding
|
||||
\section g722_page_sec_1 What does it do?
|
||||
@@ -60,6 +51,13 @@ enum
|
||||
G722_PACKED = 0x0002
|
||||
};
|
||||
|
||||
#ifndef INT16_MAX
|
||||
#define INT16_MAX 32767
|
||||
#endif
|
||||
#ifndef INT16_MIN
|
||||
#define INT16_MIN (-32768)
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/*! TRUE if the operating in the special ITU test mode, with the band split filters
|
||||
@@ -136,48 +134,19 @@ typedef struct
|
||||
int out_bits;
|
||||
} g722_decode_state_t;
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C"
|
||||
{
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*! Initialise an G.722 encode context.
|
||||
\param s The G.722 encode context.
|
||||
\param rate The required bit rate for the G.722 data.
|
||||
The valid rates are 64000, 56000 and 48000.
|
||||
\param options
|
||||
\return A pointer to the G.722 encode context, or NULL for error. */
|
||||
g722_encode_state_t *g722_encode_init(g722_encode_state_t *s, int rate, int options);
|
||||
|
||||
int g722_encode_release(g722_encode_state_t *s);
|
||||
|
||||
/*! Encode a buffer of linear PCM data to G.722
|
||||
\param s The G.722 context.
|
||||
\param g722_data The G.722 data produced.
|
||||
\param amp The audio sample buffer.
|
||||
\param len The number of samples in the buffer.
|
||||
\return The number of bytes of G.722 data produced. */
|
||||
int g722_encode(g722_encode_state_t *s, uint8_t g722_data[], const int16_t amp[], int len);
|
||||
|
||||
/*! Initialise an G.722 decode context.
|
||||
\param s The G.722 decode context.
|
||||
\param rate The bit rate of the G.722 data.
|
||||
The valid rates are 64000, 56000 and 48000.
|
||||
\param options
|
||||
\return A pointer to the G.722 decode context, or NULL for error. */
|
||||
g722_decode_state_t *g722_decode_init(g722_decode_state_t *s, int rate, int options);
|
||||
|
||||
int g722_decode_release(g722_decode_state_t *s);
|
||||
|
||||
/*! Decode a buffer of G.722 data to linear PCM.
|
||||
\param s The G.722 context.
|
||||
\param amp The audio sample buffer.
|
||||
\param g722_data
|
||||
\param len
|
||||
\return The number of samples returned. */
|
||||
int g722_decode(g722_decode_state_t *s, int16_t amp[], const uint8_t g722_data[], int len);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,137 +0,0 @@
|
||||
/*
|
||||
* VoIPcodecs - a series of DSP components for telephony
|
||||
*
|
||||
* bitstream.c - Bitstream composition and decomposition routines.
|
||||
*
|
||||
* Written by Steve Underwood <steveu@coppice.org>
|
||||
*
|
||||
* Copyright (C) 2006 Steve Underwood
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the Lesser Lesser GNU General Public License version 2.1.1, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* $Id: bitstream.c,v 1.8 2007/08/20 15:22:21 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include "inttypes.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "g722_telephony.h"
|
||||
#include "g722_bitstream.h"
|
||||
|
||||
void bitstream_put(bitstream_state_t *s, uint8_t **c, unsigned int value, int bits)
|
||||
{
|
||||
value &= ((1 << bits) - 1);
|
||||
if (s->residue + bits <= 32)
|
||||
{
|
||||
s->bitstream |= (value << s->residue);
|
||||
s->residue += bits;
|
||||
}
|
||||
while (s->residue >= 8)
|
||||
{
|
||||
s->residue -= 8;
|
||||
*(*c)++ = (uint8_t) (s->bitstream & 0xFF);
|
||||
s->bitstream >>= 8;
|
||||
}
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
void bitstream_put2(bitstream_state_t *s, uint8_t **c, unsigned int value, int bits)
|
||||
{
|
||||
value &= ((1 << bits) - 1);
|
||||
if (s->residue + bits <= 32)
|
||||
{
|
||||
s->bitstream = (s->bitstream << bits) | value;
|
||||
s->residue += bits;
|
||||
}
|
||||
while (s->residue >= 8)
|
||||
{
|
||||
s->residue -= 8;
|
||||
*(*c)++ = (uint8_t) ((s->bitstream >> s->residue) & 0xFF);
|
||||
}
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
unsigned int bitstream_get(bitstream_state_t *s, const uint8_t **c, int bits)
|
||||
{
|
||||
unsigned int x;
|
||||
|
||||
while (s->residue < (unsigned int) bits)
|
||||
{
|
||||
x = (unsigned int) *(*c)++;
|
||||
s->bitstream |= (x << s->residue);
|
||||
s->residue += 8;
|
||||
}
|
||||
s->residue -= bits;
|
||||
x = s->bitstream & ((1 << bits) - 1);
|
||||
s->bitstream >>= bits;
|
||||
return x;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
unsigned int bitstream_get2(bitstream_state_t *s, const uint8_t **c, int bits)
|
||||
{
|
||||
unsigned int x;
|
||||
|
||||
while (s->residue < (unsigned int) bits)
|
||||
{
|
||||
x = (unsigned int) *(*c)++;
|
||||
s->bitstream = (s->bitstream << 8) | x;
|
||||
s->residue += 8;
|
||||
}
|
||||
s->residue -= bits;
|
||||
x = (s->bitstream >> s->residue) & ((1 << bits) - 1);
|
||||
return x;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
void bitstream_flush(bitstream_state_t *s, uint8_t **c)
|
||||
{
|
||||
if (s->residue > 0)
|
||||
{
|
||||
*(*c)++ = (uint8_t) ((s->bitstream << (8 - s->residue)) & 0xFF);
|
||||
s->residue = 0;
|
||||
}
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
void bitstream_flush2(bitstream_state_t *s, uint8_t **c)
|
||||
{
|
||||
if (s->residue > 0)
|
||||
{
|
||||
*(*c)++ = (uint8_t) ((s->bitstream << (8 - s->residue)) & 0xFF);
|
||||
s->residue = 0;
|
||||
}
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
bitstream_state_t *bitstream_init(bitstream_state_t *s)
|
||||
{
|
||||
if (s == NULL)
|
||||
return NULL;
|
||||
s->bitstream = 0;
|
||||
s->residue = 0;
|
||||
return s;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
/*- End of file ------------------------------------------------------------*/
|
||||
@@ -1,89 +0,0 @@
|
||||
/*
|
||||
* VoIPcodecs - a series of DSP components for telephony
|
||||
*
|
||||
* bitstream.h - Bitstream composition and decomposition routines.
|
||||
*
|
||||
* Written by Steve Underwood <steveu@coppice.org>
|
||||
*
|
||||
* Copyright (C) 2006 Steve Underwood
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the Lesser GNU General Public License version 2.1, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* $Id: bitstream.h,v 1.8 2007/12/13 11:31:32 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
|
||||
#if !defined(_SPANDSP_BITSTREAM_H_)
|
||||
#define _SPANDSP_BITSTREAM_H_
|
||||
|
||||
/*! \page bitstream_page Bitstream composition and decomposition
|
||||
\section bitstream_page_sec_1 What does it do?
|
||||
|
||||
\section bitstream_page_sec_2 How does it work?
|
||||
*/
|
||||
|
||||
/*! Bitstream handler state */
|
||||
typedef struct
|
||||
{
|
||||
/*! The bit stream. */
|
||||
unsigned int bitstream;
|
||||
/*! The residual bits in bitstream. */
|
||||
unsigned int residue;
|
||||
} bitstream_state_t;
|
||||
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/*! \brief Put a chunk of bits into the output buffer.
|
||||
\param s A pointer to the bitstream context.
|
||||
\param c A pointer to the bitstream output buffer.
|
||||
\param value The value to be pushed into the output buffer.
|
||||
\param bits The number of bits of value to be pushed. 1 to 25 bit is valid. */
|
||||
void bitstream_put(bitstream_state_t *s, uint8_t **c, unsigned int value, int bits);
|
||||
|
||||
void bitstream_put2(bitstream_state_t *s, uint8_t **c, unsigned int value, int bits);
|
||||
|
||||
/*! \brief Get a chunk of bits from the input buffer.
|
||||
\param s A pointer to the bitstream context.
|
||||
\param c A pointer to the bitstream input buffer.
|
||||
\param bits The number of bits of value to be grabbed. 1 to 25 bit is valid.
|
||||
\return The value retrieved from the input buffer. */
|
||||
unsigned int bitstream_get(bitstream_state_t *s, const uint8_t **c, int bits);
|
||||
|
||||
unsigned int bitstream_get2(bitstream_state_t *s, const uint8_t **c, int bits);
|
||||
|
||||
/*! \brief Flush any residual bit to the output buffer.
|
||||
\param s A pointer to the bitstream context.
|
||||
\param c A pointer to the bitstream output buffer. */
|
||||
void bitstream_flush(bitstream_state_t *s, uint8_t **c);
|
||||
|
||||
void bitstream_flush2(bitstream_state_t *s, uint8_t **c);
|
||||
|
||||
/*! \brief Initialise a bitstream context.
|
||||
\param s A pointer to the bitstream context.
|
||||
\return A pointer to the bitstream context. */
|
||||
bitstream_state_t *bitstream_init(bitstream_state_t *s);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
/*- End of file ------------------------------------------------------------*/
|
||||
@@ -1,157 +0,0 @@
|
||||
/*
|
||||
* VoIPcodecs - a series of DSP components for telephony
|
||||
*
|
||||
* dc_restore.h - General telephony routines to restore the zero D.C.
|
||||
* level to audio which has a D.C. bias.
|
||||
*
|
||||
* Written by Steve Underwood <steveu@coppice.org>
|
||||
*
|
||||
* Copyright (C) 2001 Steve Underwood
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* $Id: dc_restore.h,v 1.18 2007/04/08 08:16:17 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
|
||||
#if !defined(_SPANDSP_DC_RESTORE_H_)
|
||||
#define _SPANDSP_DC_RESTORE_H_
|
||||
|
||||
/*! \page dc_restore_page Removing DC bias from a signal
|
||||
|
||||
\section dc_restore_page_sec_1 What does it do?
|
||||
|
||||
Telecoms signals often contain considerable DC, but DC upsets a lot of signal
|
||||
processing functions. Placing a zero DC restorer at the front of the processing
|
||||
chain can often simplify the downstream processing.
|
||||
|
||||
\section dc_restore_page_sec_2 How does it work?
|
||||
|
||||
The DC restorer uses a leaky integrator to provide a long-ish term estimate of
|
||||
the DC bias in the signal. A 32 bit estimate is used for the 16 bit audio, so
|
||||
the noise introduced by the estimation can be keep in the lower bits, and the 16
|
||||
bit DC value, which is subtracted from the signal, is fairly clean. The
|
||||
following code fragment shows the algorithm used. dc_bias is a 32 bit integer,
|
||||
while the sample and the resulting clean_sample are 16 bit integers.
|
||||
|
||||
dc_bias += ((((int32_t) sample << 15) - dc_bias) >> 14);
|
||||
clean_sample = sample - (dc_bias >> 15);
|
||||
*/
|
||||
|
||||
/*!
|
||||
Zero DC restoration descriptor. This defines the working state for a single
|
||||
instance of DC content filter.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
int32_t state;
|
||||
} dc_restore_state_t;
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
static __inline__ void dc_restore_init(dc_restore_state_t *dc)
|
||||
{
|
||||
dc->state = 0;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static __inline__ int16_t dc_restore(dc_restore_state_t *dc, int16_t sample)
|
||||
{
|
||||
dc->state += ((((int32_t) sample << 15) - dc->state) >> 14);
|
||||
return (int16_t) (sample - (dc->state >> 15));
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static __inline__ int16_t dc_restore_estimate(dc_restore_state_t *dc)
|
||||
{
|
||||
return (int16_t) (dc->state >> 15);
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static __inline__ int16_t saturate(int32_t amp)
|
||||
{
|
||||
int16_t amp16;
|
||||
|
||||
/* Hopefully this is optimised for the common case - not clipping */
|
||||
amp16 = (int16_t) amp;
|
||||
if (amp == amp16)
|
||||
return amp16;
|
||||
if (amp > INT16_MAX)
|
||||
return INT16_MAX;
|
||||
return INT16_MIN;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
/*#ifdef _MSC_VER
|
||||
__inline float rintf (float flt)
|
||||
{
|
||||
_asm
|
||||
{ fld flt
|
||||
frndint
|
||||
}
|
||||
}
|
||||
|
||||
__inline double rint(double dbl)
|
||||
{
|
||||
__asm
|
||||
{
|
||||
fld dbl
|
||||
frndint
|
||||
}
|
||||
}
|
||||
|
||||
__inline long lrintf (float flt)
|
||||
{
|
||||
long retval;
|
||||
_asm
|
||||
{ fld flt
|
||||
fistp retval
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
#endif
|
||||
*/
|
||||
|
||||
static __inline__ int16_t fsaturatef(float famp)
|
||||
{
|
||||
if (famp > 32767.0)
|
||||
return INT16_MAX;
|
||||
if (famp < -32768.0)
|
||||
return INT16_MIN;
|
||||
return (int16_t) rintf(famp);
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static __inline__ int16_t fsaturate(double damp)
|
||||
{
|
||||
if (damp > 32767.0)
|
||||
return INT16_MAX;
|
||||
if (damp < -32768.0)
|
||||
return INT16_MIN;
|
||||
return (int16_t) rint(damp);
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
/*- End of file ------------------------------------------------------------*/
|
||||
+46
-47
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* VoIPcodecs - a series of DSP components for telephony
|
||||
* SpanDSP - a series of DSP components for telephony
|
||||
*
|
||||
* g722_decode.c - The ITU G.722 codec, decode part.
|
||||
*
|
||||
@@ -7,21 +7,10 @@
|
||||
*
|
||||
* Copyright (C) 2005 Steve Underwood
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2, or
|
||||
* the Lesser GNU General Public License version 2.1, as published by
|
||||
* the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
* Despite my general liking of the GPL, I place my own contributions
|
||||
* to this code in the public domain for the benefit of all mankind -
|
||||
* even the slimy ones who might try to proprietize my work and use it
|
||||
* to my detriment.
|
||||
*
|
||||
* Based in part on a single channel G.722 codec which is:
|
||||
*
|
||||
@@ -29,7 +18,11 @@
|
||||
* Computer Science, Speech Group
|
||||
* Chengxiang Lu and Alex Hauptmann
|
||||
*
|
||||
* $Id: g722_decode.c,v 1.20 2008/02/09 15:32:56 steveu Exp $
|
||||
* $Id$
|
||||
*
|
||||
* rtphone: taken from Asterisk (codecs/g722). The only change is that the
|
||||
* decoder saturates its output instead of letting a corrupt stream wrap
|
||||
* around int16 (Asterisk casts (rlow << 1) and (xout >> 11) directly).
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@@ -38,18 +31,37 @@
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include "g722_inttypes.h"
|
||||
#include <stdio.h>
|
||||
#include <inttypes.h>
|
||||
#include <memory.h>
|
||||
#include <stdlib.h>
|
||||
#if defined(HAVE_TGMATH_H)
|
||||
#if 0
|
||||
#include <tgmath.h>
|
||||
#endif
|
||||
#include <math.h>
|
||||
|
||||
#include "g722_telephony.h"
|
||||
#include "g722_dc_restore.h"
|
||||
#include "g722.h"
|
||||
|
||||
#if !defined(FALSE)
|
||||
#define FALSE 0
|
||||
#endif
|
||||
#if !defined(TRUE)
|
||||
#define TRUE (!FALSE)
|
||||
#endif
|
||||
|
||||
static __inline__ int16_t saturate(int32_t amp)
|
||||
{
|
||||
int16_t amp16;
|
||||
|
||||
/* Hopefully this is optimised for the common case - not clipping */
|
||||
amp16 = (int16_t) amp;
|
||||
if (amp == amp16)
|
||||
return amp16;
|
||||
if (amp > INT16_MAX)
|
||||
return INT16_MAX;
|
||||
return INT16_MIN;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static void block4(g722_decode_state_t *s, int band, int d);
|
||||
|
||||
static void block4(g722_decode_state_t *s, int band, int d)
|
||||
@@ -177,14 +189,8 @@ int g722_decode_release(g722_decode_state_t *s)
|
||||
|
||||
int g722_decode(g722_decode_state_t *s, int16_t amp[], const uint8_t g722_data[], int len)
|
||||
{
|
||||
static const int wl[8] =
|
||||
{
|
||||
-60, -30, 58, 172, 334, 538, 1198, 3042
|
||||
};
|
||||
static const int rl42[16] =
|
||||
{
|
||||
0, 7, 6, 5, 4, 3, 2, 1, 7, 6, 5, 4, 3, 2, 1, 0
|
||||
};
|
||||
static const int wl[8] = {-60, -30, 58, 172, 334, 538, 1198, 3042 };
|
||||
static const int rl42[16] = {0, 7, 6, 5, 4, 3, 2, 1, 7, 6, 5, 4, 3, 2, 1, 0 };
|
||||
static const int ilb[32] =
|
||||
{
|
||||
2048, 2093, 2139, 2186, 2233, 2282, 2332,
|
||||
@@ -193,18 +199,9 @@ int g722_decode(g722_decode_state_t *s, int16_t amp[], const uint8_t g722_data[]
|
||||
3228, 3298, 3371, 3444, 3520, 3597, 3676,
|
||||
3756, 3838, 3922, 4008
|
||||
};
|
||||
static const int wh[3] =
|
||||
{
|
||||
0, -214, 798
|
||||
};
|
||||
static const int rh2[4] =
|
||||
{
|
||||
2, 1, 2, 1
|
||||
};
|
||||
static const int qm2[4] =
|
||||
{
|
||||
-7408, -1616, 7408, 1616
|
||||
};
|
||||
static const int wh[3] = {0, -214, 798};
|
||||
static const int rh2[4] = {2, 1, 2, 1};
|
||||
static const int qm2[4] = {-7408, -1616, 7408, 1616};
|
||||
static const int qm4[16] =
|
||||
{
|
||||
0, -20456, -12896, -8968,
|
||||
@@ -246,6 +243,7 @@ int g722_decode(g722_decode_state_t *s, int16_t amp[], const uint8_t g722_data[]
|
||||
{
|
||||
3, -11, 12, 32, -210, 951, 3876, -805, 362, -156, 53, -11,
|
||||
};
|
||||
|
||||
int dlowt;
|
||||
int rlow;
|
||||
int ihigh;
|
||||
@@ -369,19 +367,20 @@ int g722_decode(g722_decode_state_t *s, int16_t amp[], const uint8_t g722_data[]
|
||||
|
||||
if (s->itu_test_mode)
|
||||
{
|
||||
amp[outlen++] = (int16_t) (rlow << 1);
|
||||
amp[outlen++] = saturate(rlow << 1);
|
||||
amp[outlen++] = (int16_t) (rhigh << 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (s->eight_k)
|
||||
{
|
||||
amp[outlen++] = (int16_t) rlow;
|
||||
amp[outlen++] = saturate(rlow << 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Apply the receive QMF */
|
||||
memcpy(s->x, &s->x[2], 22*sizeof(s->x[0]));
|
||||
for (i = 0; i < 22; i++)
|
||||
s->x[i] = s->x[i + 2];
|
||||
s->x[22] = rlow + rhigh;
|
||||
s->x[23] = rlow - rhigh;
|
||||
|
||||
@@ -392,8 +391,8 @@ int g722_decode(g722_decode_state_t *s, int16_t amp[], const uint8_t g722_data[]
|
||||
xout2 += s->x[2*i]*qmf_coeffs[i];
|
||||
xout1 += s->x[2*i + 1]*qmf_coeffs[11 - i];
|
||||
}
|
||||
amp[outlen++] = (int16_t) (xout1 >> 12);
|
||||
amp[outlen++] = (int16_t) (xout2 >> 12);
|
||||
amp[outlen++] = saturate(xout1 >> 11);
|
||||
amp[outlen++] = saturate(xout2 >> 11);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+35
-24
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* VoIPcodecs - a series of DSP components for telephony
|
||||
* SpanDSP - a series of DSP components for telephony
|
||||
*
|
||||
* g722_encode.c - The ITU G.722 codec, encode part.
|
||||
*
|
||||
@@ -9,19 +9,10 @@
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2, or
|
||||
* the Lesser GNU General Public License version 2.1, as published by
|
||||
* the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
* Despite my general liking of the GPL, I place my own contributions
|
||||
* to this code in the public domain for the benefit of all mankind -
|
||||
* even the slimy ones who might try to proprietize my work and use it
|
||||
* to my detriment.
|
||||
*
|
||||
* Based on a single channel 64kbps only G.722 codec which is:
|
||||
*
|
||||
@@ -29,7 +20,7 @@
|
||||
* Computer Science, Speech Group
|
||||
* Chengxiang Lu and Alex Hauptmann
|
||||
*
|
||||
* $Id: g722_encode.c,v 1.18 2008/02/09 15:32:56 steveu Exp $
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@@ -38,18 +29,37 @@
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include "g722_inttypes.h"
|
||||
#include <stdio.h>
|
||||
#include <inttypes.h>
|
||||
#include <memory.h>
|
||||
#include <stdlib.h>
|
||||
#if defined(HAVE_TGMATH_H)
|
||||
#if 0
|
||||
#include <tgmath.h>
|
||||
#endif
|
||||
#include <math.h>
|
||||
|
||||
#include "g722_telephony.h"
|
||||
#include "g722_dc_restore.h"
|
||||
#include "g722.h"
|
||||
|
||||
#if !defined(FALSE)
|
||||
#define FALSE 0
|
||||
#endif
|
||||
#if !defined(TRUE)
|
||||
#define TRUE (!FALSE)
|
||||
#endif
|
||||
|
||||
static __inline__ int16_t saturate(int32_t amp)
|
||||
{
|
||||
int16_t amp16;
|
||||
|
||||
/* Hopefully this is optimised for the common case - not clipping */
|
||||
amp16 = (int16_t) amp;
|
||||
if (amp == amp16)
|
||||
return amp16;
|
||||
if (amp > INT16_MAX)
|
||||
return INT16_MAX;
|
||||
return INT16_MIN;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static void block4(g722_encode_state_t *s, int band, int d)
|
||||
{
|
||||
int wd1;
|
||||
@@ -269,13 +279,14 @@ int g722_encode(g722_encode_state_t *s, uint8_t g722_data[], const int16_t amp[]
|
||||
{
|
||||
if (s->eight_k)
|
||||
{
|
||||
xlow = amp[j++];
|
||||
xlow = amp[j++] >> 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Apply the transmit QMF */
|
||||
/* Shuffle the buffer down */
|
||||
memcpy(s->x, &s->x[2], 22*sizeof(s->x[0]));
|
||||
for (i = 0; i < 22; i++)
|
||||
s->x[i] = s->x[i + 2];
|
||||
s->x[22] = amp[j++];
|
||||
s->x[23] = amp[j++];
|
||||
|
||||
@@ -287,8 +298,8 @@ int g722_encode(g722_encode_state_t *s, uint8_t g722_data[], const int16_t amp[]
|
||||
sumodd += s->x[2*i]*qmf_coeffs[i];
|
||||
sumeven += s->x[2*i + 1]*qmf_coeffs[11 - i];
|
||||
}
|
||||
xlow = (sumeven + sumodd) >> 13;
|
||||
xhigh = (sumeven - sumodd) >> 13;
|
||||
xlow = (sumeven + sumodd) >> 14;
|
||||
xhigh = (sumeven - sumodd) >> 14;
|
||||
}
|
||||
}
|
||||
/* Block 1L, SUBTRA */
|
||||
|
||||
@@ -1,103 +0,0 @@
|
||||
/*
|
||||
* SpanDSP - a series of DSP components for telephony
|
||||
*
|
||||
* inttypes.h - a fudge for MSVC, which lacks this header
|
||||
*
|
||||
* Written by Steve Underwood <steveu@coppice.org>
|
||||
*
|
||||
* Copyright (C) 2006 Michael Jerris
|
||||
*
|
||||
*
|
||||
* This file is released in the public domain.
|
||||
*
|
||||
*/
|
||||
|
||||
#if !defined(_INTTYPES_H_)
|
||||
#define _INTTYPES_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#if (_MSC_VER >= 1400) // VC8+
|
||||
#ifndef _CRT_SECURE_NO_DEPRECATE
|
||||
#define _CRT_SECURE_NO_DEPRECATE
|
||||
#endif
|
||||
#ifndef _CRT_NONSTDC_NO_DEPRECATE
|
||||
#define _CRT_NONSTDC_NO_DEPRECATE
|
||||
#endif
|
||||
#endif // VC8+
|
||||
|
||||
#include <windows.h>
|
||||
typedef unsigned __int8 uint8_t;
|
||||
typedef unsigned __int16 uint16_t;
|
||||
typedef unsigned __int32 uint32_t;
|
||||
typedef unsigned __int64 uint64_t;
|
||||
typedef __int8 int8_t;
|
||||
typedef __int16 int16_t;
|
||||
typedef __int32 int32_t;
|
||||
typedef __int64 int64_t;
|
||||
#define inline __inline
|
||||
#define __inline__ __inline
|
||||
#define INT16_MAX 0x7fff
|
||||
#define INT16_MIN (-INT16_MAX - 1)
|
||||
#define _MMX_H_
|
||||
|
||||
/* disable the following warnings
|
||||
* C4100: The formal parameter is not referenced in the body of the function. The unreferenced parameter is ignored.
|
||||
* C4200: Non standard extension C zero sized array
|
||||
* C4706: assignment within conditional expression
|
||||
* C4244: conversion from 'type1' to 'type2', possible loss of data
|
||||
* C4295: array is too small to include a terminating null character
|
||||
* C4125: decimal digit terminates octal escape sequence
|
||||
*/
|
||||
#pragma warning(disable:4100 4200 4706 4295 4125)
|
||||
|
||||
//#pragma comment(lib, "ws2_32.lib")
|
||||
|
||||
#define strncasecmp _strnicmp
|
||||
#define strcasecmp _stricmp
|
||||
#define snprintf _snprintf
|
||||
|
||||
#if !defined(INFINITY)
|
||||
#define INFINITY 0x7fffffff
|
||||
#endif
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
#define PACKAGE "voipcodecs"
|
||||
#define VERSION "0.0.1andabit"
|
||||
|
||||
#ifndef INT32_MAX
|
||||
#define INT32_MAX (2147483647)
|
||||
#endif
|
||||
#ifndef INT32_MIN
|
||||
#define INT32_MIN (-2147483647 - 1)
|
||||
#endif
|
||||
|
||||
#define PRId8 "d"
|
||||
#define PRId16 "d"
|
||||
#ifndef PRId32
|
||||
# define PRId32 "ld"
|
||||
#endif
|
||||
|
||||
#ifndef PRId64
|
||||
# define PRId64 "lld"
|
||||
#endif
|
||||
|
||||
#define PRIu8 "u"
|
||||
#define PRIu16 "u"
|
||||
#ifndef PRIu32
|
||||
# define PRIu32 "lu"
|
||||
#endif
|
||||
#ifndef PRIu64
|
||||
# define PRIu64 "llu"
|
||||
#endif
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _INTTYPES_H_
|
||||
|
||||
@@ -1,74 +0,0 @@
|
||||
/*
|
||||
* VoIPcodecs - a series of DSP components for telephony
|
||||
*
|
||||
* telephony.h - some very basic telephony definitions
|
||||
*
|
||||
* Written by Steve Underwood <steveu@coppice.org>
|
||||
*
|
||||
* Copyright (C) 2003 Steve Underwood
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the Lesser GNU General Public License version 2.1, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* $Id: telephony.h,v 1.10 2007/04/05 19:20:50 steveu Exp $
|
||||
*/
|
||||
|
||||
#if !defined(_SPANDSP_TELEPHONY_H_)
|
||||
#define _SPANDSP_TELEPHONY_H_
|
||||
|
||||
#define SAMPLE_RATE 8000
|
||||
|
||||
/* This is based on A-law, but u-law is only 0.03dB different */
|
||||
#define DBM0_MAX_POWER (3.14f + 3.02f)
|
||||
#define DBM0_MAX_SINE_POWER (3.14f)
|
||||
/* This is based on the ITU definition of dbOv in G.100.1 */
|
||||
#define DBOV_MAX_POWER (0.0f)
|
||||
#define DBOV_MAX_SINE_POWER (-3.02f)
|
||||
|
||||
/*! \brief A handler for pure receive. The buffer cannot be altered. */
|
||||
typedef int (span_rx_handler_t)(void *s, const int16_t amp[], int len);
|
||||
|
||||
/*! \brief A handler for receive, where the buffer can be altered. */
|
||||
typedef int (span_mod_handler_t)(void *s, int16_t amp[], int len);
|
||||
|
||||
/*! \brief A handler for transmit, where the buffer will be filled. */
|
||||
typedef int (span_tx_handler_t)(void *s, int16_t amp[], int max_len);
|
||||
|
||||
#define ms_to_samples(t) (((t)*SAMPLE_RATE)/1000)
|
||||
|
||||
#if !defined(FALSE)
|
||||
#define FALSE 0
|
||||
#endif
|
||||
#if !defined(TRUE)
|
||||
#define TRUE (!FALSE)
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#if (_MSC_VER >= 1400) // VC8+
|
||||
#define vc_assert(expr) assert(expr);__analysis_assume( expr )
|
||||
#else
|
||||
#define vc_assert(expr) assert(expr)
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
/* C++ doesn't seem to have sane rounding functions/macros yet */
|
||||
#ifndef _MSC_VER
|
||||
#define lrint(x) ((long int) (x))
|
||||
#define lrintf(x) ((long int) (x))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
/*- End of file ------------------------------------------------------------*/
|
||||
@@ -1,300 +0,0 @@
|
||||
/*
|
||||
* G.722 Plugin codec for OpenH323/OPAL
|
||||
*
|
||||
* Copyright (C) 2008 by Hermon Labs, All Rights Reserved
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.0 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS"
|
||||
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
* the License for the specific language governing rights and limitations
|
||||
* under the License.
|
||||
*
|
||||
* The Original Code is Open Phone Abstraction Library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Eugene Mednikov
|
||||
*
|
||||
* Contributor(s): ______________________________________.
|
||||
*
|
||||
* $Revision: 23265 $
|
||||
* $Author: rjongbloed $
|
||||
* $Date: 2009-08-25 04:25:58 +0300 (вт, 25 серп 2009) $
|
||||
*/
|
||||
|
||||
#ifndef PLUGIN_CODEC_DLL_EXPORTS
|
||||
#include "plugin-config.h"
|
||||
#endif
|
||||
|
||||
#include <codec/opalplugin.h>
|
||||
|
||||
#include "VoIPCodecs/inttypes.h"
|
||||
#include "VoIPCodecs/g722.h"
|
||||
|
||||
|
||||
#define INCLUDE_SDP_16000_VERSION 0
|
||||
|
||||
/* Due to a spec error, clock rate is 8kHz even though this is 16kHz codec,
|
||||
see RFC3551/4.5.2. So some of these values have to be lied about so that
|
||||
the OPAL system gets it right.
|
||||
*/
|
||||
#define CLOCK_RATE 8000 // Clock rate is not samples/second in this case!
|
||||
#define BITS_PER_SECOND 64000 // raw bits per second
|
||||
#define FRAME_TIME 1000 // Microseconds in a millisecond
|
||||
#define SAMPLES_PER_FRAME 16 // Samples in a millisecond
|
||||
#define BYTES_PER_FRAME 8 // Bytes in a millisecond
|
||||
#define MAX_FRAMES_PER_PACKET 90 // 90 milliseconds, which means RTP packets smaller than 1500 bytes typical LAN maximum
|
||||
#define PREF_FRAMES_PER_PACKET 20 // 20 milliseconds
|
||||
|
||||
static const char L16Desc[] = "PCM-16-16kHz"; // Cannot use "L16" as usual, force 16kHz PCM
|
||||
static const char g722[] = "G.722-64k";
|
||||
static const char sdpG722[] = "G722";
|
||||
|
||||
#if INCLUDE_SDP_16000_VERSION
|
||||
static const char g722_16[] = "G.722-16kHz";
|
||||
#endif
|
||||
|
||||
#define PAYLOAD_CODE 9
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void * create_encoder(const struct PluginCodec_Definition * codec)
|
||||
{
|
||||
return g722_encode_init(NULL, BITS_PER_SECOND, 0);
|
||||
}
|
||||
|
||||
static void destroy_encoder(const struct PluginCodec_Definition * codec, void * context)
|
||||
{
|
||||
g722_encode_release(context);
|
||||
}
|
||||
|
||||
static int encode(const struct PluginCodec_Definition * codec,
|
||||
void * context,
|
||||
const void * from,
|
||||
unsigned * fromLen,
|
||||
void * to,
|
||||
unsigned * toLen,
|
||||
unsigned int * flag)
|
||||
{
|
||||
g722_encode_state_t * state = context;
|
||||
|
||||
if (*toLen < *fromLen / 4)
|
||||
return 0; // Destination buffer not big enough
|
||||
|
||||
*toLen = g722_encode(state, to, from, *fromLen / 2);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void * create_decoder(const struct PluginCodec_Definition * codec)
|
||||
{
|
||||
return g722_decode_init(NULL, BITS_PER_SECOND, 0);
|
||||
}
|
||||
|
||||
static void destroy_decoder(const struct PluginCodec_Definition * codec, void * context)
|
||||
{
|
||||
g722_decode_release(context);
|
||||
}
|
||||
|
||||
|
||||
static int decode(const struct PluginCodec_Definition * codec,
|
||||
void * _context,
|
||||
const void * from,
|
||||
unsigned * fromLen,
|
||||
void * to,
|
||||
unsigned * toLen,
|
||||
unsigned int * flag)
|
||||
{
|
||||
g722_decode_state_t * state = _context;
|
||||
|
||||
if (*toLen < *fromLen * 4)
|
||||
return 0; // Destination buffer not big enough
|
||||
|
||||
*toLen = g722_decode(state, to, from, *fromLen) * 2;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static struct PluginCodec_information licenseInfo = {
|
||||
1084181196, // timestamp = Mon 10 May 2004 09:26:36 AM UTC
|
||||
|
||||
"Eugene Mednikov", // source code author
|
||||
"1.0", // source code version
|
||||
"em@hermonlabs.com", // source code email
|
||||
"http://www.hermonlabs.com", // source code URL
|
||||
"Copyright (C) 2008 by Hermon Labs, All Rights Reserved", // source code copyright
|
||||
"MPL 1.0", // source code license
|
||||
PluginCodec_License_MPL, // source code license
|
||||
|
||||
"ITU G.722", // codec description
|
||||
"Steve Underwood", // codec author
|
||||
NULL, // codec version
|
||||
"steveu@coppice.org", // codec email
|
||||
NULL, // codec URL
|
||||
NULL, // codec copyright information
|
||||
NULL, // codec license
|
||||
PluginCodec_License_LGPL // codec license code
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static struct PluginCodec_Definition g722CodecDefn[] =
|
||||
{
|
||||
#if INCLUDE_SDP_16000_VERSION
|
||||
// Include a version for SIP/SDP that indicates the more logical, though
|
||||
// incorrect by RFC3551/4.5.2, 16000Hz version of G.722. We use dynamic
|
||||
// payload types to avoid conflict with the compliant 8000Hz version.
|
||||
{
|
||||
// encoder
|
||||
PLUGIN_CODEC_VERSION_WIDEBAND, // codec API version
|
||||
&licenseInfo, // license information
|
||||
|
||||
PluginCodec_MediaTypeAudio | // audio codec
|
||||
PluginCodec_InputTypeRaw | // raw input data
|
||||
PluginCodec_OutputTypeRaw | // raw output data
|
||||
PluginCodec_RTPTypeDynamic, // specified RTP type
|
||||
|
||||
g722_16, // text decription
|
||||
L16Desc, // source format
|
||||
g722_16, // destination format
|
||||
|
||||
0, // user data
|
||||
|
||||
16000, // samples per second
|
||||
BITS_PER_SECOND, // raw bits per second
|
||||
FRAME_TIME, // microseconds per frame
|
||||
SAMPLES_PER_FRAME, // samples per frame
|
||||
BYTES_PER_FRAME, // bytes per frame
|
||||
PREF_FRAMES_PER_PACKET, // recommended number of frames per packet
|
||||
MAX_FRAMES_PER_PACKET, // maximum number of frames per packe
|
||||
PAYLOAD_CODE, // IANA RTP payload code
|
||||
sdpG722, // RTP payload name
|
||||
|
||||
create_encoder, // create codec function
|
||||
destroy_encoder, // destroy codec
|
||||
encode, // encode/decode
|
||||
NULL, // codec controls
|
||||
|
||||
0, // h323CapabilityType
|
||||
NULL // h323CapabilityData
|
||||
},
|
||||
|
||||
{
|
||||
// decoder
|
||||
PLUGIN_CODEC_VERSION_WIDEBAND, // codec API version
|
||||
&licenseInfo, // license information
|
||||
|
||||
PluginCodec_MediaTypeAudio | // audio codec
|
||||
PluginCodec_InputTypeRaw | // raw input data
|
||||
PluginCodec_OutputTypeRaw | // raw output data
|
||||
PluginCodec_RTPTypeDynamic, // specified RTP type
|
||||
|
||||
g722_16, // text decription
|
||||
g722_16, // source format
|
||||
L16Desc, // destination format
|
||||
|
||||
0, // user data
|
||||
|
||||
16000, // samples per second
|
||||
BITS_PER_SECOND, // raw bits per second
|
||||
FRAME_TIME, // microseconds per frame
|
||||
SAMPLES_PER_FRAME, // samples per frame
|
||||
BYTES_PER_FRAME, // bytes per frame
|
||||
PREF_FRAMES_PER_PACKET, // recommended number of frames per packet
|
||||
MAX_FRAMES_PER_PACKET, // maximum number of frames per packe
|
||||
PAYLOAD_CODE, // IANA RTP payload code
|
||||
sdpG722, // RTP payload name
|
||||
|
||||
create_decoder, // create codec function
|
||||
destroy_decoder, // destroy codec
|
||||
decode, // encode/decode
|
||||
NULL, // codec controls
|
||||
|
||||
0, // h323CapabilityType
|
||||
NULL // h323CapabilityData
|
||||
},
|
||||
#endif
|
||||
|
||||
// Standards compliant version
|
||||
{
|
||||
// encoder
|
||||
PLUGIN_CODEC_VERSION_WIDEBAND, // codec API version
|
||||
&licenseInfo, // license information
|
||||
|
||||
PluginCodec_MediaTypeAudio | // audio codec
|
||||
PluginCodec_InputTypeRaw | // raw input data
|
||||
PluginCodec_OutputTypeRaw | // raw output data
|
||||
PluginCodec_RTPTypeExplicit, // specified RTP type
|
||||
|
||||
g722, // text decription
|
||||
L16Desc, // source format
|
||||
g722, // destination format
|
||||
|
||||
0, // user data
|
||||
|
||||
CLOCK_RATE, // samples per second
|
||||
BITS_PER_SECOND, // raw bits per second
|
||||
FRAME_TIME, // microseconds per frame
|
||||
SAMPLES_PER_FRAME, // samples per frame
|
||||
BYTES_PER_FRAME, // bytes per frame
|
||||
PREF_FRAMES_PER_PACKET, // recommended number of frames per packet
|
||||
MAX_FRAMES_PER_PACKET, // maximum number of frames per packe
|
||||
PAYLOAD_CODE, // IANA RTP payload code
|
||||
sdpG722, // RTP payload name
|
||||
|
||||
create_encoder, // create codec function
|
||||
destroy_encoder, // destroy codec
|
||||
encode, // encode/decode
|
||||
NULL, // codec controls
|
||||
|
||||
PluginCodec_H323AudioCodec_g722_64k, // h323CapabilityType
|
||||
NULL // h323CapabilityData
|
||||
},
|
||||
|
||||
{
|
||||
// decoder
|
||||
PLUGIN_CODEC_VERSION_WIDEBAND, // codec API version
|
||||
&licenseInfo, // license information
|
||||
|
||||
PluginCodec_MediaTypeAudio | // audio codec
|
||||
PluginCodec_InputTypeRaw | // raw input data
|
||||
PluginCodec_OutputTypeRaw | // raw output data
|
||||
PluginCodec_RTPTypeExplicit, // specified RTP type
|
||||
|
||||
g722, // text decription
|
||||
g722, // source format
|
||||
L16Desc, // destination format
|
||||
|
||||
0, // user data
|
||||
|
||||
CLOCK_RATE, // samples per second
|
||||
BITS_PER_SECOND, // raw bits per second
|
||||
FRAME_TIME, // microseconds per frame
|
||||
SAMPLES_PER_FRAME, // samples per frame
|
||||
BYTES_PER_FRAME, // bytes per frame
|
||||
PREF_FRAMES_PER_PACKET, // recommended number of frames per packet
|
||||
MAX_FRAMES_PER_PACKET, // maximum number of frames per packe
|
||||
PAYLOAD_CODE, // IANA RTP payload code
|
||||
sdpG722, // RTP payload name
|
||||
|
||||
create_decoder, // create codec function
|
||||
destroy_decoder, // destroy codec
|
||||
decode, // encode/decode
|
||||
NULL, // codec controls
|
||||
|
||||
PluginCodec_H323AudioCodec_g722_64k, // h323CapabilityType
|
||||
NULL // h323CapabilityData
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
PLUGIN_CODEC_IMPLEMENT_ALL(G722, g722CodecDefn, PLUGIN_CODEC_VERSION_WIDEBAND)
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
Reference in New Issue
Block a user